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