[ruby-core:33557] [Ruby 1.9-Feature#4068] Replace current standard Date/DateTime library with home_run
From:
tadayoshi funaba <redmine@...>
Date:
2010-12-04 01:05:11 UTC
List:
ruby-core #33557
Issue #4068 has been updated by tadayoshi funaba.
File switch_hitter.patch added
File bm2.rb added
i've just written initial version of "switch_hitter".
i've attached the patch to trunk and a script.
swich_hitter provides both speed and quality.
swich_hitter has highly compatibility with the current date.
> d = Date.new(2001,2,23) #=> #<Date::Light: 2001-02-23 (2451964)>
> d + 1 #=> #<Date::Light: 2001-02-24 (2451965)>
> d += Rational(3,2) #=> #<Date::Right: 2001-02-24 (2451965/1,0,2299161.0)>
> d.ctime #=> "Sat Feb 24 12:00:00 2001"
> d = Date.new(1582,10,15) #=> #<Date::Light: 1582-10-15 (2299161)>
> d - 1 #=> #<Date::Right: 1582-10-04 (4598319/2,0,2299161.0)>
swich_hitter is fast only on purely small gregorian dates.
i didn't enough replace methods with c yet.
however, switch_hitter and home_run are even on some cases, i think.
switch_hitter:
user system total real
Date::valid_date?: 0.030000 0.000000 0.030000 ( 0.029646)
Date::new: 0.040000 0.000000 0.040000 ( 0.042592)
Date#to_s: 0.080000 0.000000 0.080000 ( 0.072524)
Date#+: 0.040000 0.000000 0.040000 ( 0.042738)
Date#-: 0.050000 0.000000 0.050000 ( 0.048020)
[Date]#sort: 0.220000 0.000000 0.220000 ( 0.224903)
home_run:
user system total real
Date::valid_date?: 0.030000 0.000000 0.030000 ( 0.022076)
Date::new: 0.040000 0.000000 0.040000 ( 0.048092)
Date#to_s: 0.100000 0.000000 0.100000 ( 0.093716)
Date#+: 0.030000 0.000000 0.030000 ( 0.034154)
Date#-: 0.040000 0.000000 0.040000 ( 0.033082)
[Date]#sort: 0.270000 0.000000 0.270000 ( 0.262382)
----------------------------------------
http://redmine.ruby-lang.org/issues/show/4068
----------------------------------------
http://redmine.ruby-lang.org
Attachments (2)
switch_hitter.patch
(39.3 KB, text/x-diff)
Index: lib/date.rb
===================================================================
--- lib/date.rb (revision 30074)
+++ lib/date.rb (working copy)
@@ -1,5 +1,5 @@
#
-# date.rb - date and time library
+# date.rb <switch_hitter> - date and time library
#
# Author: Tadayoshi Funaba 1998-2010
#
@@ -719,25 +719,14 @@
def self.gregorian_leap? (y) y % 4 == 0 && y % 100 != 0 || y % 400 == 0 end
class << self; alias_method :leap?, :gregorian_leap? end
- class << self; alias_method :new!, :new end
- def self.valid_jd? (jd, sg=ITALY)
- !!_valid_jd?(jd, sg)
- end
+ def self.valid_jd?(*args) raise NotImplementedError end
+ def self.valid_ordinal?(*args) raise NotImplementedError end
+ def self.valid_civil?(*args) raise NotImplementedError end
- def self.valid_ordinal? (y, d, sg=ITALY)
- !!_valid_ordinal?(y, d, sg)
- end
-
- def self.valid_civil? (y, m, d, sg=ITALY)
- !!_valid_civil?(y, m, d, sg)
- end
-
class << self; alias_method :valid_date?, :valid_civil? end
- def self.valid_commercial? (y, w, d, sg=ITALY)
- !!_valid_commercial?(y, w, d, sg)
- end
+ def self.valid_commercial?(*args) raise NotImplementedError end
def self.valid_weeknum? (y, w, d, f, sg=ITALY) # :nodoc:
!!_valid_weeknum?(y, w, d, f, sg)
@@ -762,10 +751,7 @@
# +jd+ is the Julian Day Number; if not specified, it defaults to
# 0.
# +sg+ specifies the Day of Calendar Reform.
- def self.jd(jd=0, sg=ITALY)
- jd = _valid_jd?(jd, sg)
- new!(jd_to_ajd(jd, 0, 0), 0, sg)
- end
+ def self.jd(*args) raise NotImplementedError end
# Create a new Date object from an Ordinal Date, specified
# by year +y+ and day-of-year +d+. +d+ can be negative,
@@ -777,12 +763,7 @@
# Number day 0.
#
# +sg+ specifies the Day of Calendar Reform.
- def self.ordinal(y=-4712, d=1, sg=ITALY)
- unless jd = _valid_ordinal?(y, d, sg)
- raise ArgumentError, 'invalid date'
- end
- new!(jd_to_ajd(jd, 0, 0), 0, sg)
- end
+ def self.ordinal(*args) raise NotImplementedError end
# Create a new Date object for the Civil Date specified by
# year +y+, month +m+, and day-of-month +d+.
@@ -797,12 +778,7 @@
# Julian Day Number day 0.
#
# +sg+ specifies the Day of Calendar Reform.
- def self.civil(y=-4712, m=1, d=1, sg=ITALY)
- unless jd = _valid_civil?(y, m, d, sg)
- raise ArgumentError, 'invalid date'
- end
- new!(jd_to_ajd(jd, 0, 0), 0, sg)
- end
+ def self.civil(*args) raise NotImplementedError end
class << self; alias_method :new, :civil end
@@ -820,12 +796,7 @@
# Julian Day Number day 0.
#
# +sg+ specifies the Day of Calendar Reform.
- def self.commercial(y=-4712, w=1, d=1, sg=ITALY)
- unless jd = _valid_commercial?(y, w, d, sg)
- raise ArgumentError, 'invalid date'
- end
- new!(jd_to_ajd(jd, 0, 0), 0, sg)
- end
+ def self.commercial(*args) raise NotImplementedError end
def self.weeknum(y=-4712, w=0, d=1, f=0, sg=ITALY)
unless jd = _valid_weeknum?(y, w, d, f, sg)
@@ -1034,10 +1005,7 @@
#
# An ArgumentError will be raised if +str+ cannot be
# parsed.
- def self.strptime(str='-4712-01-01', fmt='%F', sg=ITALY)
- elem = _strptime(str, fmt)
- new_by_frags(elem, sg)
- end
+ def self.strptime(*args) raise NotImplementedError end
# Create a new Date object by parsing from a String,
# without specifying the format.
@@ -1054,43 +1022,18 @@
# Day Number day 0.
#
# +sg+ specifies the Day of Calendar Reform.
- def self.parse(str='-4712-01-01', comp=true, sg=ITALY)
- elem = _parse(str, comp)
- new_by_frags(elem, sg)
- end
+ def self.parse(*args) raise NotImplementedError end
- def self.iso8601(str='-4712-01-01', sg=ITALY) # :nodoc:
- elem = _iso8601(str)
- new_by_frags(elem, sg)
- end
+ def self.iso8601(*args) raise NotImplementedError end
+ def self.rfc3339(*args) raise NotImplementedError end
+ def self.xmlschema(*args) raise NotImplementedError end
+ def self.rfc2822(*args) raise NotImplementedError end
- def self.rfc3339(str='-4712-01-01T00:00:00+00:00', sg=ITALY) # :nodoc:
- elem = _rfc3339(str)
- new_by_frags(elem, sg)
- end
-
- def self.xmlschema(str='-4712-01-01', sg=ITALY) # :nodoc:
- elem = _xmlschema(str)
- new_by_frags(elem, sg)
- end
-
- def self.rfc2822(str='Mon, 1 Jan -4712 00:00:00 +0000', sg=ITALY) # :nodoc:
- elem = _rfc2822(str)
- new_by_frags(elem, sg)
- end
-
class << self; alias_method :rfc822, :rfc2822 end
- def self.httpdate(str='Mon, 01 Jan -4712 00:00:00 GMT', sg=ITALY) # :nodoc:
- elem = _httpdate(str)
- new_by_frags(elem, sg)
- end
+ def self.httpdate(*args) raise NotImplementedError end
+ def self.jisx0301(*args) raise NotImplementedError end
- def self.jisx0301(str='-4712-01-01', sg=ITALY) # :nodoc:
- elem = _jisx0301(str)
- new_by_frags(elem, sg)
- end
-
class << self
def once(*ids) # :nodoc: -- restricted
@@ -1103,7 +1046,7 @@
end
end;
end
- end
+ end # <<dummy
private :once
@@ -1128,20 +1071,17 @@
#
# Using one of the factory methods such as Date::civil is
# generally easier and safer.
- def initialize(ajd=0, of=0, sg=ITALY)
- @ajd, @of, @sg = ajd, of, sg
- @__ca__ = {}
- end
+ def initialize(*args) raise NotImplementedError end
# Get the date as an Astronomical Julian Day Number.
def ajd() @ajd end
# Get the date as an Astronomical Modified Julian Day Number.
- def amjd() ajd_to_amjd(@ajd) end
+ def amjd() ajd_to_amjd(ajd) end
once :amjd
- def daynum() ajd_to_jd(@ajd, @of) end
+ def daynum() ajd_to_jd(ajd, offset) end
once :daynum
private :daynum
@@ -1162,16 +1102,16 @@
once :jd, :day_fraction, :mjd, :ld
# Get the date as a Civil Date, [year, month, day_of_month]
- def civil() jd_to_civil(jd, @sg) end # :nodoc:
+ def civil() jd_to_civil(jd, start) end # :nodoc:
# Get the date as an Ordinal Date, [year, day_of_year]
- def ordinal() jd_to_ordinal(jd, @sg) end # :nodoc:
+ def ordinal() jd_to_ordinal(jd, start) end # :nodoc:
# Get the date as a Commercial Date, [year, week_of_year, day_of_week]
- def commercial() jd_to_commercial(jd, @sg) end # :nodoc:
+ def commercial() jd_to_commercial(jd, start) end # :nodoc:
- def weeknum0() jd_to_weeknum(jd, 0, @sg) end # :nodoc:
- def weeknum1() jd_to_weeknum(jd, 1, @sg) end # :nodoc:
+ def weeknum0() jd_to_weeknum(jd, 0, start) end # :nodoc:
+ def weeknum1() jd_to_weeknum(jd, 1, start) end # :nodoc:
once :civil, :ordinal, :commercial, :weeknum0, :weeknum1
private :civil, :ordinal, :commercial, :weeknum0, :weeknum1
@@ -1275,7 +1215,7 @@
private :nth_kday?
# Is the current date old-style (Julian Calendar)?
- def julian? () jd < @sg end
+ def julian? () jd < start end
# Is the current date new-style (Gregorian Calendar)?
def gregorian? () !julian? end
@@ -1302,7 +1242,7 @@
def start() @sg end
# Create a copy of this Date object using a new Day of Calendar Reform.
- def new_start(sg=self.class::ITALY) self.class.new!(@ajd, @of, sg) end
+ def new_start(*args) raise NotImplementedError end
# Create a copy of this Date object that uses the Italian/Catholic
# Day of Calendar Reform.
@@ -1322,12 +1262,7 @@
def offset() @of end
- def new_offset(of=0)
- if String === of
- of = Rational(zone_to_diff(of) || 0, 86400)
- end
- self.class.new!(@ajd, of, @sg)
- end
+ def new_offset(*args) raise NotImplementedError end
private :offset, :new_offset
@@ -1340,12 +1275,7 @@
#
# If +n+ is not a Numeric, a TypeError will be thrown. In
# particular, two Dates cannot be added to each other.
- def + (n)
- case n
- when Numeric; return self.class.new!(@ajd + n, @of, @sg)
- end
- raise TypeError, 'expected numeric'
- end
+ def + (*args) raise NotImplementedError end
# If +x+ is a Numeric value, create a new Date object that is
# +x+ days earlier than the current one.
@@ -1355,13 +1285,7 @@
# date is than +x+.
#
# If +x+ is neither Numeric nor a Date, a TypeError is raised.
- def - (x)
- case x
- when Numeric; return self.class.new!(@ajd - x, @of, @sg)
- when Date; return @ajd - x.ajd
- end
- raise TypeError, 'expected numeric or date'
- end
+ def - (*args) raise NotImplementedError end
# Compare this date with another date.
#
@@ -1376,8 +1300,8 @@
# considered as falling on midnight UTC.
def <=> (other)
case other
- when Numeric; return @ajd <=> other
- when Date; return @ajd <=> other.ajd
+ when Numeric; return ajd <=> other
+ when Date; return ajd <=> other.ajd
else
begin
l, r = other.coerce(self)
@@ -1388,6 +1312,17 @@
nil
end
+ def coerce(other)
+ case other
+ when Light
+ return Right.new!(other.ajd, other.__send__(:offset), other.start), self
+ when Right
+ return self, Right.new!(self.ajd, self.__send__(:offset), self.start)
+ else
+ super
+ end
+ end
+
# The relationship operator for Date.
#
# Compares dates by Julian Day Number. When comparing
@@ -1423,7 +1358,7 @@
y, m = (year * 12 + (mon - 1) + n).divmod(12)
m, = (m + 1) .divmod(1)
d = mday
- until jd2 = _valid_civil?(y, m, d, @sg)
+ until jd2 = _valid_civil?(y, m, d, start)
d -= 1
raise ArgumentError, 'invalid date' unless d > 0
end
@@ -1486,11 +1421,11 @@
def eql? (other) Date === other && self == other end
# Calculate a hash value for this date.
- def hash() @ajd.hash end
+ def hash() ajd.hash end
# Return internal object state as a programmer-readable string.
def inspect
- format('#<%s: %s (%s,%s,%s)>', self.class, to_s, @ajd, @of, @sg)
+ format('#<%s: %s (%s,%s,%s)>', self.class, to_s, ajd, offset, start)
end
# Return the date as a human-readable string.
@@ -1559,6 +1494,8 @@
#
class DateTime < Date
+ def self.new(*args) raise NotImplementedError end
+
# Create a new DateTime object corresponding to the specified
# Julian Day Number +jd+ and hour +h+, minute +min+, second +s+.
#
@@ -1572,16 +1509,7 @@
# +sg+ specifies the Day of Calendar Reform.
#
# All day/time values default to 0.
- def self.jd(jd=0, h=0, min=0, s=0, of=0, sg=ITALY)
- unless (jd = _valid_jd?(jd, sg)) &&
- (fr = _valid_time?(h, min, s))
- raise ArgumentError, 'invalid date'
- end
- if String === of
- of = Rational(zone_to_diff(of) || 0, 86400)
- end
- new!(jd_to_ajd(jd, fr, of), of, sg)
- end
+ def self.jd(*args) raise NotImplementedError end
# Create a new DateTime object corresponding to the specified
# Ordinal Date and hour +h+, minute +min+, second +s+.
@@ -1597,16 +1525,7 @@
#
# +y+ defaults to -4712, and +d+ to 1; this is Julian Day Number
# day 0. The time values default to 0.
- def self.ordinal(y=-4712, d=1, h=0, min=0, s=0, of=0, sg=ITALY)
- unless (jd = _valid_ordinal?(y, d, sg)) &&
- (fr = _valid_time?(h, min, s))
- raise ArgumentError, 'invalid date'
- end
- if String === of
- of = Rational(zone_to_diff(of) || 0, 86400)
- end
- new!(jd_to_ajd(jd, fr, of), of, sg)
- end
+ def self.ordinal(*args) raise NotImplementedError end
# Create a new DateTime object corresponding to the specified
# Civil Date and hour +h+, minute +min+, second +s+.
@@ -1622,19 +1541,8 @@
#
# +y+ defaults to -4712, +m+ to 1, and +d+ to 1; this is Julian Day
# Number day 0. The time values default to 0.
- def self.civil(y=-4712, m=1, d=1, h=0, min=0, s=0, of=0, sg=ITALY)
- unless (jd = _valid_civil?(y, m, d, sg)) &&
- (fr = _valid_time?(h, min, s))
- raise ArgumentError, 'invalid date'
- end
- if String === of
- of = Rational(zone_to_diff(of) || 0, 86400)
- end
- new!(jd_to_ajd(jd, fr, of), of, sg)
- end
+ def self.civil(*args) raise NotImplementedError end
- class << self; alias_method :new, :civil end
-
# Create a new DateTime object corresponding to the specified
# Commercial Date and hour +h+, minute +min+, second +s+.
#
@@ -1650,16 +1558,7 @@
# +y+ defaults to -4712, +w+ to 1, and +d+ to 1; this is
# Julian Day Number day 0.
# The time values default to 0.
- def self.commercial(y=-4712, w=1, d=1, h=0, min=0, s=0, of=0, sg=ITALY)
- unless (jd = _valid_commercial?(y, w, d, sg)) &&
- (fr = _valid_time?(h, min, s))
- raise ArgumentError, 'invalid date'
- end
- if String === of
- of = Rational(zone_to_diff(of) || 0, 86400)
- end
- new!(jd_to_ajd(jd, fr, of), of, sg)
- end
+ def self.commercial(*args) raise NotImplementedError end
def self.weeknum(y=-4712, w=0, d=1, f=0, h=0, min=0, s=0, of=0, sg=ITALY) # :nodoc:
unless (jd = _valid_weeknum?(y, w, d, f, sg)) &&
@@ -1715,10 +1614,7 @@
#
# An ArgumentError will be raised if +str+ cannot be
# parsed.
- def self.strptime(str='-4712-01-01T00:00:00+00:00', fmt='%FT%T%z', sg=ITALY)
- elem = _strptime(str, fmt)
- new_by_frags(elem, sg)
- end
+ def self.strptime(*args) raise NotImplementedError end
# Create a new DateTime object by parsing from a String,
# without specifying the format.
@@ -1735,17 +1631,142 @@
# Day Number day 0.
#
# +sg+ specifies the Day of Calendar Reform.
- def self.parse(str='-4712-01-01T00:00:00+00:00', comp=true, sg=ITALY)
+ def self.parse(*args) raise NotImplementedError end
+
+ def self.iso8601(*args) raise NotImplementedError end
+ def self.rfc3339(*args) raise NotImplementedError end
+ def self.xmlschema(*args) raise NotImplementedError end
+ def self.rfc2822(*args) raise NotImplementedError end
+
+ class << self; alias_method :rfc822, :rfc2822 end
+
+ def self.httpdate(*args) raise NotImplementedError end
+ def self.jisx0301(*args) raise NotImplementedError end
+
+ public :hour, :min, :sec, :sec_fraction, :zone, :offset, :new_offset,
+ :minute, :second, :second_fraction
+
+ def to_s # 4p
+ format('%.4d-%02d-%02dT%02d:%02d:%02d%s',
+ year, mon, mday, hour, min, sec, zone)
+ end
+
+end
+
+require 'date_core'
+
+class Time
+
+ def to_time(*args) raise NotImplementedError end
+ def to_date(*args) raise NotImplementedError end
+ def to_datetime(*args) raise NotImplementedError end
+
+end
+
+class Date
+
+ def to_time(*args) raise NotImplementedError end
+ def to_date(*args) raise NotImplementedError end
+ def to_datetime(*args) raise NotImplementedError end
+
+ # Create a new DateTime object representing the current time.
+ #
+ # +sg+ specifies the Day of Calendar Reform.
+ def self.now(*args) raise NotImplementedError end
+
+ private_class_method :now
+
+end
+
+class DateTime < Date
+
+ def to_time(*args) raise NotImplementedError end
+ def to_date(*args) raise NotImplementedError end
+ def to_datetime(*args) raise NotImplementedError end
+
+ private_class_method :today
+ public_class_method :now
+
+end
+
+class Date::Right < Date
+
+ def self.valid_jd? (jd, sg=ITALY)
+ !!_valid_jd?(jd, sg)
+ end
+
+ def self.valid_ordinal? (y, d, sg=ITALY)
+ !!_valid_ordinal?(y, d, sg)
+ end
+
+ def self.valid_civil? (y, m, d, sg=ITALY)
+ !!_valid_civil?(y, m, d, sg)
+ end
+
+ class << self; alias_method :valid_date?, :valid_civil? end
+
+ def self.valid_commercial? (y, w, d, sg=ITALY)
+ !!_valid_commercial?(y, w, d, sg)
+ end
+
+ def self.new!(ajd=0, of=0, sg=ITALY)
+ d = allocate
+ d.instance_eval do
+ @ajd, @of, @sg = ajd, of, sg
+ @__ca__ = {}
+ end
+ d
+ end
+
+ def self.jd(jd=0, sg=ITALY)
+ jd = _valid_jd?(jd, sg)
+ new!(jd_to_ajd(jd, 0, 0), 0, sg)
+ end
+
+ def self.ordinal(y=-4712, d=1, sg=ITALY)
+ unless jd = _valid_ordinal?(y, d, sg)
+ raise ArgumentError, 'invalid date'
+ end
+ new!(jd_to_ajd(jd, 0, 0), 0, sg)
+ end
+
+ def self.civil(y=-4712, m=1, d=1, sg=ITALY)
+ unless jd = _valid_civil?(y, m, d, sg)
+ raise ArgumentError, 'invalid date'
+ end
+ new!(jd_to_ajd(jd, 0, 0), 0, sg)
+ end
+
+ class << self; alias_method :new, :civil end
+
+ def self.commercial(y=-4712, w=1, d=1, sg=ITALY)
+ unless jd = _valid_commercial?(y, w, d, sg)
+ raise ArgumentError, 'invalid date'
+ end
+ new!(jd_to_ajd(jd, 0, 0), 0, sg)
+ end
+
+ def self.strptime(str='-4712-01-01', fmt='%F', sg=ITALY)
+ elem = _strptime(str, fmt)
+ new_by_frags(elem, sg)
+ end
+
+ def self.parse(str='-4712-01-01', comp=true, sg=ITALY)
elem = _parse(str, comp)
new_by_frags(elem, sg)
end
- def self.iso8601(str='-4712-01-01T00:00:00+00:00', sg=ITALY) # :nodoc:
+ def self.iso8601(str='-4712-01-01', sg=ITALY) # :nodoc:
elem = _iso8601(str)
new_by_frags(elem, sg)
end
- def self.xmlschema(str='-4712-01-01T00:00:00+00:00', sg=ITALY) # :nodoc:
+ def self.rfc3339(str='-4712-01-01T00:00:00+00:00', sg=ITALY) # :nodoc:
+ elem = _rfc3339(str)
+ new_by_frags(elem, sg)
+ end
+
+ def self.xmlschema(str='-4712-01-01', sg=ITALY) # :nodoc:
elem = _xmlschema(str)
new_by_frags(elem, sg)
end
@@ -1762,87 +1783,123 @@
new_by_frags(elem, sg)
end
- def self.jisx0301(str='-4712-01-01T00:00:00+00:00', sg=ITALY) # :nodoc:
+ def self.jisx0301(str='-4712-01-01', sg=ITALY) # :nodoc:
elem = _jisx0301(str)
new_by_frags(elem, sg)
end
- public :hour, :min, :sec, :sec_fraction, :zone, :offset, :new_offset,
- :minute, :second, :second_fraction
+ def + (n)
+ case n
+ when Numeric; return self.class.new!(ajd + n, offset, start)
+ end
+ raise TypeError, 'expected numeric'
+ end
- def to_s # 4p
- format('%.4d-%02d-%02dT%02d:%02d:%02d%s',
- year, mon, mday, hour, min, sec, zone)
+ def - (x)
+ case x
+ when Numeric; return self.class.new!(ajd - x, offset, start)
+ when Date; return ajd - x.ajd
+ end
+ raise TypeError, 'expected numeric or date'
end
end
-class Time
+class DateTime::Right < DateTime
- def to_time() getlocal end
+ def self.new!(*args) raise NotImplementedError end
- def to_date
- jd = Date.__send__(:civil_to_jd, year, mon, mday, Date::ITALY)
- Date.new!(Date.__send__(:jd_to_ajd, jd, 0, 0), 0, Date::ITALY)
+ def self.jd(jd=0, h=0, min=0, s=0, of=0, sg=ITALY)
+ unless (jd = _valid_jd?(jd, sg)) &&
+ (fr = _valid_time?(h, min, s))
+ raise ArgumentError, 'invalid date'
+ end
+ if String === of
+ of = Rational(zone_to_diff(of) || 0, 86400)
+ end
+ new!(jd_to_ajd(jd, fr, of), of, sg)
end
- def to_datetime
- jd = DateTime.__send__(:civil_to_jd, year, mon, mday, DateTime::ITALY)
- fr = DateTime.__send__(:time_to_day_fraction, hour, min, [sec, 59].min) +
- Rational(subsec, 86400)
- of = Rational(utc_offset, 86400)
- DateTime.new!(DateTime.__send__(:jd_to_ajd, jd, fr, of),
- of, DateTime::ITALY)
+ def self.ordinal(y=-4712, d=1, h=0, min=0, s=0, of=0, sg=ITALY)
+ unless (jd = _valid_ordinal?(y, d, sg)) &&
+ (fr = _valid_time?(h, min, s))
+ raise ArgumentError, 'invalid date'
+ end
+ if String === of
+ of = Rational(zone_to_diff(of) || 0, 86400)
+ end
+ new!(jd_to_ajd(jd, fr, of), of, sg)
end
-end
+ def self.civil(y=-4712, m=1, d=1, h=0, min=0, s=0, of=0, sg=ITALY)
+ unless (jd = _valid_civil?(y, m, d, sg)) &&
+ (fr = _valid_time?(h, min, s))
+ raise ArgumentError, 'invalid date'
+ end
+ if String === of
+ of = Rational(zone_to_diff(of) || 0, 86400)
+ end
+ new!(jd_to_ajd(jd, fr, of), of, sg)
+ end
-class Date
+ class << self; alias_method :new, :civil end
- def to_time() Time.local(year, mon, mday) end
- def to_date() self end
- def to_datetime() DateTime.new!(jd_to_ajd(jd, 0, 0), @of, @sg) end
+ def self.commercial(y=-4712, w=1, d=1, h=0, min=0, s=0, of=0, sg=ITALY)
+ unless (jd = _valid_commercial?(y, w, d, sg)) &&
+ (fr = _valid_time?(h, min, s))
+ raise ArgumentError, 'invalid date'
+ end
+ if String === of
+ of = Rational(zone_to_diff(of) || 0, 86400)
+ end
+ new!(jd_to_ajd(jd, fr, of), of, sg)
+ end
- # Create a new Date object representing today.
- #
- # +sg+ specifies the Day of Calendar Reform.
- def self.today(sg=ITALY)
- t = Time.now
- jd = civil_to_jd(t.year, t.mon, t.mday, sg)
- new!(jd_to_ajd(jd, 0, 0), 0, sg)
+ def self.strptime(str='-4712-01-01T00:00:00+00:00', fmt='%FT%T%z', sg=ITALY)
+ elem = _strptime(str, fmt)
+ new_by_frags(elem, sg)
end
- # Create a new DateTime object representing the current time.
- #
- # +sg+ specifies the Day of Calendar Reform.
- def self.now(sg=ITALY)
- t = Time.now
- jd = civil_to_jd(t.year, t.mon, t.mday, sg)
- fr = time_to_day_fraction(t.hour, t.min, [t.sec, 59].min) +
- Rational(t.subsec, 86400)
- of = Rational(t.utc_offset, 86400)
- new!(jd_to_ajd(jd, fr, of), of, sg)
+ def self.parse(str='-4712-01-01T00:00:00+00:00', comp=true, sg=ITALY)
+ elem = _parse(str, comp)
+ new_by_frags(elem, sg)
end
- private_class_method :now
+ def self.iso8601(str='-4712-01-01T00:00:00+00:00', sg=ITALY) # :nodoc:
+ elem = _iso8601(str)
+ new_by_frags(elem, sg)
+ end
-end
+ def self.xmlschema(str='-4712-01-01T00:00:00+00:00', sg=ITALY) # :nodoc:
+ elem = _xmlschema(str)
+ new_by_frags(elem, sg)
+ end
-class DateTime < Date
+ def self.rfc2822(str='Mon, 1 Jan -4712 00:00:00 +0000', sg=ITALY) # :nodoc:
+ elem = _rfc2822(str)
+ new_by_frags(elem, sg)
+ end
- def to_time
- d = new_offset(0)
- d.instance_eval do
- Time.utc(year, mon, mday, hour, min, sec +
- sec_fraction)
- end.
- getlocal
+ class << self; alias_method :rfc822, :rfc2822 end
+
+ def self.httpdate(str='Mon, 01 Jan -4712 00:00:00 GMT', sg=ITALY) # :nodoc:
+ elem = _httpdate(str)
+ new_by_frags(elem, sg)
end
- def to_date() Date.new!(jd_to_ajd(jd, 0, 0), 0, @sg) end
- def to_datetime() self end
+ def self.jisx0301(str='-4712-01-01T00:00:00+00:00', sg=ITALY) # :nodoc:
+ elem = _jisx0301(str)
+ new_by_frags(elem, sg)
+ end
- private_class_method :today
- public_class_method :now
+end
+class Date::Light < Date
+
+ def yday(*args) raise NotImplementedError end
+ def cwyear(*args) raise NotImplementedError end
+ def cweek(*args) raise NotImplementedError end
+ def cwday(*args) raise NotImplementedError end
+ def leap?(*args) raise NotImplementedError end
+
end
Index: ext/date/date_core.c
===================================================================
--- ext/date/date_core.c (revision 0)
+++ ext/date/date_core.c (revision 0)
@@ -0,0 +1,819 @@
+/*
+ date_core.c <switch_hitter>: Coded by Tadayoshi Funaba 2010
+*/
+
+#include "ruby.h"
+#include <math.h>
+#include <time.h>
+
+static VALUE cDate, cDateRight, cDateLight;
+
+static void
+date_civil_to_jd_internal(int y, int m, int d, double sg,
+ long *rjd, int *rns)
+{
+ double a, b, jd;
+
+ if (m <= 2) {
+ y -= 1;
+ m += 12;
+ }
+ a = floor(y / 100.0);
+ b = 2 - a + floor(a / 4.0);
+ jd = floor(365.25 * (y + 4716)) +
+ floor(30.6001 * (m + 1)) +
+ d + b - 1524;
+ if (jd < sg) {
+ jd -= b;
+ *rns = 0;
+ } else
+ *rns = 1;
+
+ *rjd = jd;
+}
+
+static void
+date_jd_to_civil_internal(long jd, double sg,
+ int *ry, int *rm, int *rdom)
+{
+ double x, a, b, c, d, e, y, m, dom;
+
+ if (jd < sg)
+ a = jd;
+ else {
+ x = floor((jd - 1867216.25) / 36524.25);
+ a = jd + 1 + x - floor(x / 4.0);
+ }
+ b = a + 1524;
+ c = floor((b - 122.1) / 365.25);
+ d = floor(365.25 * c);
+ e = floor((b - d) / 30.6001);
+ dom = b - d - floor(30.6001 * e);
+ if (e <= 13) {
+ m = e - 1;
+ y = c - 4716;
+ } else {
+ m = e - 13;
+ y = c - 4715;
+ }
+
+ *ry = y;
+ *rm = m;
+ *rdom = dom;
+}
+
+static int date_valid_civil_p_internal(int y, int m, int d, double sg,
+ int *nm, int *nd,
+ long *rjd, int *ns);
+
+static int
+find_ldom(int y, int m, int sg,
+ long *rjd, int *ns)
+{
+ int i, nm, nd;
+
+ for (i = 0; i < 30; i++) {
+ if (date_valid_civil_p_internal(y, m, 31 - i, sg, &nm, &nd, rjd, ns))
+ return 1;
+ }
+ return 0;
+}
+
+static const int monthtab[2][13] = {
+ { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+ { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+
+inline static int
+leap_p(int y)
+{
+ return y % 4 == 0 && y % 100 != 0 || y % 400 == 0;
+}
+
+static int
+last_day_of_month(int y, int m)
+{
+ return monthtab[leap_p(y) ? 1 : 0][m];
+}
+
+static int
+date_valid_gregorian_p_internal(int y, int m, int d,
+ int *nm, int *nd)
+{
+ int last;
+
+ if (m < 0)
+ m += 13;
+
+ last = last_day_of_month(y, m);
+
+ if (d < 0) {
+
+ d = last + d + 1;
+ }
+
+ *nm = m;
+ *nd = d;
+
+ return !(m < 0 || m > 12 ||
+ d < 1 || d > last);
+}
+
+static int
+date_valid_civil_p_internal(int y, int m, int d, double sg,
+ int *nm, int *nd,
+ long *rjd, int *ns)
+{
+ int ny;
+
+ if (m < 0)
+ m += 13;
+ if (d < 0) {
+ if (!find_ldom(y, m, sg, rjd, ns))
+ return 0;
+ date_jd_to_civil_internal(*rjd + d + 1, sg, &ny, nm, nd);
+ if (ny != y || *nm != m)
+ return 0;
+ d = *nd;
+ }
+ date_civil_to_jd_internal(y, m, d, sg, rjd, ns);
+ date_jd_to_civil_internal(*rjd, sg, &ny, nm, nd);
+ if (ny != y || *nm != m || *nd != d)
+ return 0;
+ return 1;
+}
+
+#define HAVE_JD 1
+#define HAVE_CIVIL 2
+
+#define ITALY 2299161
+
+struct DateLightData
+{
+ long jd;
+ double sg;
+ int year;
+ int mon;
+ int mday;
+ unsigned flags;
+};
+
+#define get_dat1(x) \
+ struct DateLightData *dat;\
+ Data_Get_Struct(x, struct DateLightData, dat)
+
+#define get_dat2(x,y) \
+ struct DateLightData *adat, *bdat;\
+ Data_Get_Struct(x, struct DateLightData, adat);\
+ Data_Get_Struct(y, struct DateLightData, bdat)
+
+inline static VALUE
+f_kind_of_p(VALUE x, VALUE c)
+{
+ return rb_obj_is_kind_of(x, c);
+}
+
+inline static VALUE
+k_dategen_p(VALUE x)
+{
+ return f_kind_of_p(x, cDateRight);
+}
+
+inline static VALUE
+k_datelite_p(VALUE x)
+{
+ return f_kind_of_p(x, cDateLight);
+}
+
+static VALUE
+date_s_valid_civil_p(int argc, VALUE *argv, VALUE klass)
+{
+ VALUE vy, vm, vd, vsg;
+ int y, m, d, nm, nd;
+ double sg;
+
+ rb_scan_args(argc, argv, "31", &vy, &vm, &vd, &vsg);
+
+ if (!(FIXNUM_P(vy) &&
+ FIXNUM_P(vm) &&
+ FIXNUM_P(vd)))
+ return rb_funcall2(cDateRight, rb_intern("valid_civil?"), argc, argv);
+
+ if (!NIL_P(vsg))
+ sg = NUM2DBL(vsg);
+ else
+ sg = ITALY;
+
+ y = -4712;
+ m = 1;
+ d = 1;
+
+ switch (argc) {
+ case 4:
+ case 3:
+ d = NUM2LONG(vd);
+ case 2:
+ m = NUM2LONG(vm);
+ case 1:
+ y = NUM2LONG(vy);
+ }
+
+ if (isinf(sg) && sg < 0) {
+ if (!date_valid_gregorian_p_internal(y, m, d, &nm, &nd))
+ return Qfalse;
+ return Qtrue;
+ } else {
+ long jd;
+ int ns;
+
+ if (!date_valid_civil_p_internal(y, m, d, sg, &nm, &nd, &jd, &ns))
+ return Qfalse;
+ return Qtrue;
+ }
+}
+
+inline static VALUE
+datelite_s_new_internal0(VALUE klass, long jd, double sg,
+ int y, int m, int d, unsigned flags)
+{
+ struct DateLightData *dat;
+ VALUE obj;
+
+ obj = Data_Make_Struct(klass, struct DateLightData, 0, -1, dat);
+
+ dat->jd = jd;
+ dat->sg = sg;
+ dat->year = y;
+ dat->mon = m;
+ dat->mday = d;
+ dat->flags = flags;
+
+ return obj;
+}
+
+static VALUE
+datelite_s_new_internal(VALUE klass, long jd, double sg, unsigned flags)
+{
+ return datelite_s_new_internal0(klass, jd, sg, 0, 0, 0, flags);
+}
+
+static VALUE
+datelite_s_alloc(VALUE klass)
+{
+ return datelite_s_new_internal(klass, 0, 0, 0);
+}
+
+static VALUE
+date_s_jd(int argc, VALUE *argv, VALUE klass)
+{
+ VALUE vjd, vsg;
+ long jd;
+ double sg;
+
+ rb_scan_args(argc, argv, "02", &vjd, &vsg);
+
+ if (!FIXNUM_P(vjd))
+ return rb_funcall2(cDateRight, rb_intern("jd"), argc, argv);
+
+ if (!NIL_P(vsg))
+ sg = NUM2DBL(vsg);
+ else
+ sg = ITALY;
+
+ if (argc >= 1)
+ jd = NUM2LONG(vjd);
+ else
+ jd = 0;
+
+ if (jd < sg)
+ return rb_funcall2(cDateRight, rb_intern("jd"), argc, argv);
+
+ return datelite_s_new_internal(cDateLight, jd, sg, HAVE_JD);
+}
+
+static VALUE
+date_s_civil(int argc, VALUE *argv, VALUE klass)
+{
+ VALUE vy, vm, vd, vsg;
+ int y, m, d, nm, nd;
+ double sg;
+
+ rb_scan_args(argc, argv, "04", &vy, &vm, &vd, &vsg);
+
+ if (!((NIL_P(vy) || FIXNUM_P(vy)) &&
+ (NIL_P(vm) || FIXNUM_P(vm)) &&
+ (NIL_P(vd) || FIXNUM_P(vd))))
+ return rb_funcall2(cDateRight, rb_intern("new"), argc, argv);
+
+ if (!NIL_P(vsg))
+ sg = NUM2DBL(vsg);
+ else
+ sg = ITALY;
+
+ y = -4712;
+ m = 1;
+ d = 1;
+
+ switch (argc) {
+ case 4:
+ case 3:
+ d = NUM2LONG(vd);
+ case 2:
+ m = NUM2LONG(vm);
+ case 1:
+ y = NUM2LONG(vy);
+ }
+
+ if (isinf(sg) && sg < 0) {
+ if (!date_valid_gregorian_p_internal(y, m, d, &nm, &nd))
+ rb_raise(rb_eArgError, "invalid date");
+
+ return datelite_s_new_internal0(cDateLight, 0, sg, y, nm, nd, HAVE_CIVIL);
+ } else {
+ long jd;
+ int ns;
+
+ if (!date_valid_civil_p_internal(y, m, d, sg, &nm, &nd, &jd, &ns))
+ rb_raise(rb_eArgError, "invalid date");
+
+ if (!FIXABLE(jd) || !ns)
+ return rb_funcall2(cDateRight, rb_intern("new"), argc, argv);
+
+ return datelite_s_new_internal0(cDateLight, jd, sg, y, nm, nd,
+ HAVE_JD | HAVE_CIVIL);
+ }
+}
+
+static VALUE
+date_s_today(int argc, VALUE *argv, VALUE klass)
+{
+ time_t t;
+ struct tm tm;
+ VALUE vsg, a[4];
+
+ t = time(NULL);
+ localtime_r(&t, &tm);
+
+ rb_scan_args(argc, argv, "01", &vsg);
+
+ a[0] = INT2FIX(tm.tm_year + 1900);
+ a[1] = INT2FIX(tm.tm_mon + 1);
+ a[2] = INT2FIX(tm.tm_mday);
+ if (!NIL_P(vsg))
+ a[3] = vsg;
+ else
+ a[3] = INT2FIX(ITALY);
+ return date_s_civil(4, a, klass);
+}
+
+inline static void
+get_jd(struct DateLightData *x)
+{
+ if (!(x->flags & HAVE_JD)) {
+ long jd;
+ int ns;
+
+ date_civil_to_jd_internal(x->year, x->mon, x->mday, x->sg, &jd, &ns);
+ x->jd = jd;
+ }
+}
+
+inline static void
+get_civil(struct DateLightData *x)
+{
+ if (!(x->flags & HAVE_CIVIL)) {
+ int y, m, d;
+
+ date_jd_to_civil_internal(x->jd, x->sg, &y, &m, &d);
+ x->year = y;
+ x->mon = m;
+ x->mday = d;
+ }
+}
+
+static VALUE
+datelite_ajd(VALUE self)
+{
+ get_dat1(self);
+ VALUE r;
+
+ get_jd(dat);
+ r = rb_rational_new1(INT2FIX(dat->jd));
+ return rb_funcall(r, '-', 1, rb_rational_new2(INT2FIX(1), INT2FIX(2)));
+}
+
+static VALUE
+datelite_amjd(VALUE self)
+{
+ get_dat1(self);
+
+ get_jd(dat);
+ return rb_rational_new1(LONG2NUM(dat->jd - 2400001L));
+}
+
+static VALUE
+datelite_jd(VALUE self)
+{
+ get_dat1(self);
+
+ get_jd(dat);
+ return INT2FIX(dat->jd);
+}
+
+static VALUE
+datelite_mjd(VALUE self)
+{
+ get_dat1(self);
+
+ get_jd(dat);
+ return LONG2NUM(dat->jd - 2400001L);
+}
+
+static VALUE
+datelite_ld(VALUE self)
+{
+ get_dat1(self);
+
+ get_jd(dat);
+ return LONG2NUM(dat->jd - 2299160L);
+}
+
+static VALUE
+datelite_year(VALUE self)
+{
+ get_dat1(self);
+
+ get_civil(dat);
+ return INT2FIX(dat->year);
+}
+
+static VALUE
+datelite_mon(VALUE self)
+{
+ get_dat1(self);
+
+ get_civil(dat);
+ return INT2FIX(dat->mon);
+}
+
+static VALUE
+datelite_mday(VALUE self)
+{
+ get_dat1(self);
+
+ get_civil(dat);
+ return INT2FIX(dat->mday);
+}
+
+static VALUE
+datelite_wday(VALUE self)
+{
+ get_dat1(self);
+
+ get_jd(dat);
+ return INT2FIX((dat->jd + 1) % 7);
+}
+
+static VALUE
+datelite_start(VALUE self)
+{
+ get_dat1(self);
+
+ return DBL2NUM(dat->sg);
+}
+
+static VALUE
+datelite_zone(VALUE self)
+{
+ return rb_str_new2("+00:00");
+}
+
+static VALUE
+datelite_cmp(VALUE self, VALUE other)
+{
+ if (k_datelite_p(other)) {
+ get_dat2(self, other);
+
+ if (adat->flags & HAVE_JD &&
+ bdat->flags & HAVE_JD) {
+ if (adat->jd == bdat->jd)
+ return INT2FIX(0);
+ if (adat->jd < bdat->jd)
+ return INT2FIX(-1);
+ return INT2FIX(1);
+ } else {
+ get_civil(adat);
+ get_civil(bdat);
+ if (adat->year == bdat->year) {
+ if (adat->mon == bdat->mon) {
+ if (adat->mday == bdat->mday) {
+ return INT2FIX(0);
+ } else if (adat->mday < bdat->mday) {
+ return INT2FIX(-1);
+ } else {
+ return INT2FIX(1);
+ }
+ } else if (adat->mon < bdat->mon) {
+ return INT2FIX(-1);
+ } else {
+ return INT2FIX(1);
+ }
+ } else if (adat->year < bdat->year) {
+ return INT2FIX(-1);
+ } else {
+ return INT2FIX(1);
+ }
+ }
+ }
+ return rb_num_coerce_cmp(datelite_ajd(self), other, rb_intern("<=>"));
+}
+
+static VALUE
+datelite_eqeqeq(VALUE self, VALUE other)
+{
+ if (k_datelite_p(other)) {
+ get_dat2(self, other);
+
+ if (adat->flags & HAVE_JD &&
+ bdat->flags & HAVE_JD) {
+ if (adat->jd == bdat->jd)
+ return Qtrue;
+ return Qfalse;
+ } else {
+ get_civil(adat);
+ get_civil(bdat);
+ if (adat->year == bdat->year)
+ if (adat->mon == bdat->mon)
+ if (adat->mday == bdat->mday)
+ return Qtrue;
+ return Qfalse;
+ }
+ }
+ return rb_num_coerce_cmp(datelite_ajd(self), other, rb_intern("==="));
+}
+
+static VALUE
+datelite_eql_p(VALUE self, VALUE other)
+{
+ if (k_datelite_p(other)) {
+ get_dat2(self, other);
+
+ if (adat->flags & HAVE_JD &&
+ bdat->flags & HAVE_JD) {
+ if (adat->jd == bdat->jd)
+ return Qtrue;
+ return Qfalse;
+ } else {
+ get_civil(adat);
+ get_civil(bdat);
+ if (adat->year == bdat->year)
+ if (adat->mon == bdat->mon)
+ if (adat->mday == bdat->mday)
+ return Qtrue;
+ return Qfalse;
+ }
+ }
+ return rb_num_coerce_cmp(self, other, rb_intern("eql?"));
+}
+
+static VALUE
+datelite_hash(VALUE self)
+{
+ get_dat1(self);
+
+ return rb_funcall(datelite_ajd(self), rb_intern("hash"), 0);
+}
+
+static VALUE
+datelite_plus(VALUE self, VALUE other)
+{
+ switch (TYPE(other)) {
+ case T_FIXNUM:
+ {
+ get_dat1(self);
+ get_jd(dat);
+ VALUE a[2];
+
+ a[0] = LONG2NUM(dat->jd + FIX2LONG(other));
+ a[1] = DBL2NUM(dat->sg);
+ return date_s_jd(2, a, CLASS_OF(self));
+ }
+ case T_FLOAT:
+ {
+ double n = RFLOAT_VALUE(other);
+
+ if ((int)round(n) == n) {
+ get_dat1(self);
+ get_jd(dat);
+ VALUE a[2];
+
+ a[0] = DBL2NUM((double)dat->jd + n);
+ a[1] = DBL2NUM(dat->sg);
+ return date_s_jd(2, a, CLASS_OF(self));
+ }
+ }
+ }
+ {
+ get_dat1(self);
+ get_jd(dat);
+ return rb_funcall(rb_funcall
+ (cDateRight, rb_intern("jd"), 2,
+ INT2FIX(dat->jd), DBL2NUM(dat->sg)), '+', 1, other);
+ }
+}
+
+static VALUE
+datelite_minus(VALUE self, VALUE other)
+{
+ if (k_datelite_p(other)) {
+ long d;
+ get_dat2(self, other);
+
+ get_jd(adat);
+ get_jd(bdat);
+ d = adat->jd - bdat->jd;
+ return LONG2NUM(d);
+ }
+
+ switch (TYPE(other)) {
+ case T_FIXNUM:
+ {
+ get_dat1(self);
+ VALUE a[2];
+
+ get_jd(dat);
+ a[0] = LONG2NUM(dat->jd - FIX2LONG(other));
+ a[1] = DBL2NUM(dat->sg);
+ return date_s_jd(2, a, CLASS_OF(self));
+ }
+ case T_FLOAT:
+ {
+ double n = RFLOAT_VALUE(other);
+
+ if ((int)round(n) == n) {
+ get_dat1(self);
+ VALUE a[2];
+
+ get_jd(dat);
+ a[0] = DBL2NUM((double)dat->jd - n);
+ a[1] = DBL2NUM(dat->sg);
+ return date_s_jd(2, a, CLASS_OF(self));
+ }
+ }
+ }
+ {
+ get_dat1(self);
+ get_jd(dat);
+ return rb_funcall(rb_funcall
+ (cDateRight, rb_intern("jd"), 2,
+ INT2FIX(dat->jd), DBL2NUM(dat->sg)), '-', 1, other);
+ }
+}
+
+static VALUE
+datelite_succ(VALUE self)
+{
+ return datelite_plus(self, INT2FIX(1));
+}
+
+static VALUE
+datelite_to_s(VALUE self)
+{
+ get_dat1(self);
+
+ get_civil(dat);
+ return rb_sprintf("%.4d-%02d-%02d", dat->year, dat->mon, dat->mday);
+}
+
+static VALUE
+datelite_inspect(VALUE self)
+{
+ get_dat1(self);
+
+ get_civil(dat);
+ get_jd(dat);
+ return rb_sprintf("#<Date::Light: %.4d-%02d-%02d (%ld)>",
+ dat->year, dat->mon, dat->mday, dat->jd);
+}
+
+static VALUE
+datelite_zero(VALUE self)
+{
+ return INT2FIX(0);
+}
+
+static VALUE
+datelite_rzero(VALUE self)
+{
+ return rb_rational_new1(INT2FIX(0));
+}
+
+static VALUE
+datelite_false(VALUE self)
+{
+ return Qfalse;
+}
+
+static VALUE
+datelite_true(VALUE self)
+{
+ return Qtrue;
+}
+
+static VALUE
+datelite_marshal_dump(VALUE self)
+{
+ VALUE a;
+ get_dat1(self);
+
+ a = rb_assoc_new(INT2FIX(dat->jd), DBL2NUM(dat->sg));
+
+ if (FL_TEST(self, FL_EXIVAR)) {
+ rb_copy_generic_ivar(a, self);
+ FL_SET(a, FL_EXIVAR);
+ }
+
+ return a;
+}
+
+static VALUE
+datelite_marshal_load(VALUE self, VALUE a)
+{
+ get_dat1(self);
+
+ dat->jd = FIX2INT(RARRAY_PTR(a)[0]);
+ dat->sg = NUM2DBL(RARRAY_PTR(a)[1]);
+ dat->year = 0;
+ dat->mon = 0;
+ dat->mday = 0;
+
+ if (FL_TEST(a, FL_EXIVAR)) {
+ rb_copy_generic_ivar(self, a);
+ FL_SET(self, FL_EXIVAR);
+ }
+
+ return self;
+}
+
+void
+Init_date_core(void)
+{
+ cDate = rb_define_class("Date", rb_cObject);
+
+ cDateRight = rb_define_class_under(cDate, "Right", cDate);
+ cDateLight = rb_define_class_under(cDate, "Light", cDate);
+
+ rb_define_alloc_func(cDateLight, datelite_s_alloc);
+
+ rb_define_singleton_method(cDate, "valid_civil?", date_s_valid_civil_p, -1);
+ rb_define_singleton_method(cDate, "valid_date?", date_s_valid_civil_p, -1);
+ rb_define_singleton_method(cDate, "jd", date_s_jd, -1);
+ rb_define_singleton_method(cDate, "civil", date_s_civil, -1);
+ rb_define_singleton_method(cDate, "new", date_s_civil, -1);
+ rb_define_singleton_method(cDate, "today", date_s_today, -1);
+
+ rb_define_method(cDateLight, "ajd", datelite_ajd, 0);
+ rb_define_method(cDateLight, "amjd", datelite_amjd, 0);
+ rb_define_method(cDateLight, "jd", datelite_jd, 0);
+ rb_define_method(cDateLight, "mjd", datelite_mjd, 0);
+ rb_define_method(cDateLight, "ld", datelite_ld, 0);
+
+ rb_define_method(cDateLight, "year", datelite_year, 0);
+ rb_define_method(cDateLight, "mon", datelite_mon, 0);
+ rb_define_method(cDateLight, "month", datelite_mon, 0);
+ rb_define_method(cDateLight, "mday", datelite_mday, 0);
+ rb_define_method(cDateLight, "day", datelite_mday, 0);
+ rb_define_method(cDateLight, "wday", datelite_wday, 0);
+ rb_define_method(cDateLight, "day_fraction", datelite_rzero, 0);
+
+ rb_define_private_method(cDateLight, "hour", datelite_zero, 0);
+ rb_define_private_method(cDateLight, "min", datelite_zero, 0);
+ rb_define_private_method(cDateLight, "minute", datelite_zero, 0);
+ rb_define_private_method(cDateLight, "sec", datelite_zero, 0);
+ rb_define_private_method(cDateLight, "second", datelite_zero, 0);
+ rb_define_private_method(cDateLight, "sec_fraction", datelite_zero, 0);
+ rb_define_private_method(cDateLight, "second_fraction", datelite_zero, 0);
+ rb_define_private_method(cDateLight, "offset", datelite_zero, 0);
+ rb_define_private_method(cDateLight, "zone", datelite_zone, 0);
+
+ rb_define_method(cDateLight, "start", datelite_start, 0);
+
+ rb_define_method(cDateLight, "<=>", datelite_cmp, 1);
+ rb_define_method(cDateLight, "===", datelite_eqeqeq, 1);
+ rb_define_method(cDateLight, "eql?", datelite_eql_p, 1);
+ rb_define_method(cDateLight, "hash", datelite_hash, 0);
+
+ rb_define_method(cDateLight, "julian?", datelite_false, 0);
+ rb_define_method(cDateLight, "gregorian?", datelite_true, 0);
+
+ rb_define_method(cDateLight, "+", datelite_plus, 1);
+ rb_define_method(cDateLight, "-", datelite_minus, 1);
+ rb_define_method(cDateLight, "succ", datelite_succ, 0);
+ rb_define_method(cDateLight, "next", datelite_succ, 0);
+
+ rb_define_method(cDateLight, "to_s", datelite_to_s, 0);
+ rb_define_method(cDateLight, "inspect", datelite_inspect, 0);
+
+ rb_define_method(cDateLight, "marshal_dump", datelite_marshal_dump, 0);
+ rb_define_method(cDateLight, "marshal_load", datelite_marshal_load, 1);
+}
Property changes on: ext/date/date_core.c
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Index: ext/date/extconf.rb
===================================================================
--- ext/date/extconf.rb (revision 0)
+++ ext/date/extconf.rb (revision 0)
@@ -0,0 +1,2 @@
+require 'mkmf'
+create_makefile('date_core')
Property changes on: ext/date/extconf.rb
___________________________________________________________________
Added: svn:mime-type
+ text/plain
bm2.rb
(663 Bytes, application/x-ruby)