[#33640] [Ruby 1.9-Bug#4136][Open] Enumerable#reject should not inherit the receiver's instance variables — Hiro Asari <redmine@...>

Bug #4136: Enumerable#reject should not inherit the receiver's instance variables

10 messages 2010/12/08

[#33667] [Ruby 1.9-Bug#4149][Open] Documentation submission: syslog standard library — mathew murphy <redmine@...>

Bug #4149: Documentation submission: syslog standard library

11 messages 2010/12/10

[#33683] [feature:trunk] Enumerable#categorize — Tanaka Akira <akr@...>

Hi.

14 messages 2010/12/12
[#33684] Re: [feature:trunk] Enumerable#categorize — "Martin J. Dst" <duerst@...> 2010/12/12

[#33687] Towards a standardized AST for Ruby code — Magnus Holm <judofyr@...>

Hey folks,

23 messages 2010/12/12
[#33688] Re: Towards a standardized AST for Ruby code — Charles Oliver Nutter <headius@...> 2010/12/12

On Sun, Dec 12, 2010 at 9:55 AM, Magnus Holm <judofyr@gmail.com> wrote:

[#33689] Re: Towards a standardized AST for Ruby code — "Haase, Konstantin" <Konstantin.Haase@...> 2010/12/12

On Dec 12, 2010, at 17:46 , Charles Oliver Nutter wrote:

[#33763] [Ruby 1.9-Bug#4168][Open] WeakRef is unsafe to use in Ruby 1.9 — Brian Durand <redmine@...>

Bug #4168: WeakRef is unsafe to use in Ruby 1.9

43 messages 2010/12/17

[#33815] trunk warnflags build issue with curb 0.7.9? — Jon <jon.forums@...>

As this may turn out to be a 3rd party issue rather than a bug, I'd like some feedback.

11 messages 2010/12/22

[#33833] Ruby 1.9.2 is going to be released — "Yuki Sonoda (Yugui)" <yugui@...>

-----BEGIN PGP SIGNED MESSAGE-----

15 messages 2010/12/23

[#33846] [Ruby 1.9-Feature#4197][Open] Improvement of the benchmark library — Benoit Daloze <redmine@...>

Feature #4197: Improvement of the benchmark library

15 messages 2010/12/23

[#33910] [Ruby 1.9-Feature#4211][Open] Converting the Ruby and C API documentation to YARD syntax — Loren Segal <redmine@...>

Feature #4211: Converting the Ruby and C API documentation to YARD syntax

10 messages 2010/12/26

[#33923] [Ruby 1.9-Bug#4214][Open] Fiddle::WINDOWS == false on Windows — Jon Forums <redmine@...>

Bug #4214: Fiddle::WINDOWS == false on Windows

15 messages 2010/12/27

[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)

In This Thread