Feature #4068 » switch_hitter.patch
| lib/date.rb (working copy) | ||
|---|---|---|
| 
     # 
   | 
||
| 
     # date.rb - date and time library 
   | 
||
| 
     # date.rb <switch_hitter> - date and time library 
   | 
||
| 
     # 
   | 
||
| 
     # Author: Tadayoshi Funaba 1998-2010 
   | 
||
| 
     # 
   | 
||
| ... | ... | |
| 
       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) 
   | 
||
| ... | ... | |
| 
       # +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, 
   | 
||
| ... | ... | |
| 
       # 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+. 
   | 
||
| ... | ... | |
| 
       # 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 
   | 
||
| ... | ... | |
| 
       # 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) 
   | 
||
| ... | ... | |
| 
       # 
   | 
||
| 
       # 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. 
   | 
||
| ... | ... | |
| 
       # 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 
   | 
||
| ... | ... | |
| 
     	  end 
   | 
||
| 
     	end; 
   | 
||
| 
           end 
   | 
||
| 
         end 
   | 
||
| 
         end # <<dummy 
   | 
||
| 
         private :once 
   | 
||
| ... | ... | |
| 
       # 
   | 
||
| 
       # 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 
   | 
||
| ... | ... | |
| 
       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 
   | 
||
| ... | ... | |
| 
       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 
   | 
||
| ... | ... | |
| 
       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. 
   | 
||
| ... | ... | |
| 
       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 
   | 
||
| ... | ... | |
| 
       # 
   | 
||
| 
       # 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. 
   | 
||
| ... | ... | |
| 
       # 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. 
   | 
||
| 
       # 
   | 
||
| ... | ... | |
| 
       # 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) 
   | 
||
| ... | ... | |
| 
         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 
   | 
||
| ... | ... | |
| 
         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 
   | 
||
| ... | ... | |
| 
       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. 
   | 
||
| ... | ... | |
| 
     # 
   | 
||
| 
     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+. 
   | 
||
| 
       # 
   | 
||
| ... | ... | |
| 
       # +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+. 
   | 
||
| ... | ... | |
| 
       # 
   | 
||
| 
       # +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+. 
   | 
||
| ... | ... | |
| 
       # 
   | 
||
| 
       # +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+. 
   | 
||
| 
       # 
   | 
||
| ... | ... | |
| 
       # +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)) && 
   | 
||
| ... | ... | |
| 
       # 
   | 
||
| 
       # 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. 
   | 
||
| ... | ... | |
| 
       # 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 
   | 
||
| ... | ... | |
| 
         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 
   | 
||
| ext/date/date_core.c (revision 0) | ||
|---|---|---|
| 
     /* 
   | 
||
| 
       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)) { 
   | 
||