lib/numru/gphys/unumeric.rb in gphys-1.1.1 vs lib/numru/gphys/unumeric.rb in gphys-1.2.2
- old
+ new
@@ -185,12 +185,12 @@
def self::[](val, uni)
new(val, uni)
end
- @@supported_calendars = [nil,"gregorian", "standard","noleap","365_day",
- "360_day"]
+ @@supported_calendars = [nil,"gregorian", "standard", "proleptic_gregorian",
+ "noleap", "365_day", "360_day"]
def self::supported_calendar?(cal)
@@supported_calendars.include?(cal)
end
@@ -214,26 +214,39 @@
time = Units['months'].convert((year*12+mon)-(year0*12+mon0), tun)
elsif( tun =~ Units['days since 0001-01-01'] )
case calendar
when nil, "gregorian", "standard"
time = Units['days'].convert( date-since, tun )
+ when "proleptic_gregorian"
+ since = DateTime.parse(UNumeric::before_date_parse($2),false,Date::GREGORIAN)
+ time = Units['days'].convert( date-since, tun )
when "noleap", "365_day"
since_yday = since - DateTime.new(since.year,1,1) # day number of year (0..364)
since_yday = since_yday - 1 if( since.leap? && since.mon > 2 )
date_yday = date - DateTime.new(date.year,1,1)
if( date.leap? )
if date_yday >= 60.0 # after Mar1
date_yday = date_yday - 1
elsif date_yday >= 59.0 # Feb29
- raise "Feb.29 is specified, but calendar is #{calendar}."
+ raise("Feb.29 is specified, but calendar is #{calendar}.")
end
end
days = (date.year - since.year)*365 + (date_yday - since_yday)
time = Units['days'].convert( days, tun )
when "360_day" # does not work perfectly
- days = (date.year - since.year)*360 + (date.mon - since.mon)*30 + (date.day - since.day)
- time = Units['days'].convert( days, tun )
+ if date.day == 31
+ raise("day=31 is specified, but calendar is #{calendar}.")
+ end
+ if date.is_a?(DateTime)
+ date_hour,date_min,date_sec = date.hour,date.min,date.sec
+ else
+ date_hour,date_min,date_sec = 0,0,0
+ end
+ days = (date.year-since.year)*360 + (date.mon-since.mon)*30 +
+ (date.day-since.day) + Rational(date_hour-since.hour,24) +
+ Rational(date_min-since.min,1440) + Rational(date_sec-since.sec,86400)
+ time = Units['days'].convert( days.to_f, tun )
else
#raise("Unrecognized calendar: #{calendar}")
return nil
end
else
@@ -311,11 +324,16 @@
if( tun =~ Units['months since 0001-01-01'] )
datetime = since >> tun.convert( time, Units['months'] )
elsif( tun =~ Units['days since 0001-01-01'] )
case calendar
when nil, "gregorian", "standard"
+ # default: Julian calendar before 1582-10-15, Gregorian calendar afterward
datetime = since + tun.convert( time, Units['days'] )
+ when "proleptic_gregorian"
+ # Gregorian calendar extended to the past
+ since = DateTime.parse(UNumeric::before_date_parse(sincestr),false,Date::GREGORIAN)
+ datetime = since + tun.convert( time, Units['days'] )
when "noleap", "365_day"
since_yday = since - DateTime.new(since.year,1,1) # day number of year (0..364)
since_yday = since_yday - 1 if( since.leap? && since.mon > 2 )
days = since_yday + tun.convert( time, Units['days'] )
year = since.year + (days/365).to_i
@@ -325,10 +343,15 @@
when "360_day" # does not work perfectly
since_day = since - DateTime.new(since.year,since.mon,1)
days = (since.mon-1)*30 + since_day + tun.convert( time, Units['days'] )
year = since.year + (days/360).to_i
mon = ((days%360)/30).to_i + 1
- datetime = DateTime.new(year,mon,1) + days%30
+ datetime = DateTime.new(year,mon,1) + days%30 # Feb29->Mar1,Feb30->Mar2
+ #datetime = DateTime.new(year,mon,days%30 + 1) # stops if Feb29,Feb30
+ if datetime.mon != mon # Feb29,Feb30
+ $stderr.print("cannot convert #{year}-#{mon}-#{(days%30+1).to_i} to DateTime instance\n")
+ return nil
+ end
else
#raise("Unrecognized calendar: #{calendar}")
return nil
end
else