updated to the new version (based on date2 3.2.1).

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2467 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
tadf 2002-05-18 12:41:51 +00:00
parent 62f83f9f13
commit dc9cd6a8c2
6 changed files with 903 additions and 346 deletions

View File

@ -1,3 +1,8 @@
Sat May 18 21:38:11 2002 Tadayoshi Funaba <tadf@dotrb.org>
* date.rb, date/format.rb, parsedate.rb:
updated to the new version (based on date2 3.2.1).
Sat May 18 21:18:00 2002 NAKAMURA Usaku <usa@ruby-lang.org>
* win32/Makefile.sub (config.h): add VC++4/5 support about noreturn

View File

@ -1,200 +1,258 @@
# date2.rb: Written by Tadayoshi Funaba 1998-2001
# $Id: date2.rb,v 1.23 2001-01-18 12:09:47+09 tadf Exp $
# date.rb: Written by Tadayoshi Funaba 1998-2002
# $Id: date.rb,v 2.6 2002-05-14 07:43:18+09 tadf Exp $
require 'rational'
require 'date/format'
class Date
include Comparable
IDENT = 2
MONTHNAMES = [nil] + %w(January February March April May June July
August September October November December)
DAYNAMES = %w(Sunday Monday Tuesday Wednesday Thursday Friday Saturday)
ABBR_MONTHNAMES = [nil] + %w(Jan Feb Mar Apr May Jun
Jul Aug Sep Oct Nov Dec)
ABBR_DAYNAMES = %w(Sun Mon Tue Wed Thu Fri Sat)
ITALY = 2299161 # 1582-10-15
ENGLAND = 2361222 # 1752-09-14
JULIAN = false
GREGORIAN = true
class << self
def os? (jd, sg)
case sg
when Numeric; jd < sg
else; not sg
end
def self.os? (jd, sg)
case sg
when Numeric; jd < sg
else; not sg
end
end
def ns? (jd, sg) not os?(jd, sg) end
def self.ns? (jd, sg) not os?(jd, sg) end
def civil_to_jd(y, m, d, sg=GREGORIAN)
if m <= 2
y -= 1
m += 12
end
a = (y / 100.0).floor
b = 2 - a + (a / 4.0).floor
jd = (365.25 * (y + 4716)).floor +
(30.6001 * (m + 1)).floor +
d + b - 1524
if os?(jd, sg)
jd -= b
end
jd
def self.civil_to_jd(y, m, d, sg=GREGORIAN)
if m <= 2
y -= 1
m += 12
end
def jd_to_civil(jd, sg=GREGORIAN)
if os?(jd, sg)
a = jd
else
x = ((jd - 1867216.25) / 36524.25).floor
a = jd + 1 + x - (x / 4.0).floor
end
b = a + 1524
c = ((b - 122.1) / 365.25).floor
d = (365.25 * c).floor
e = ((b - d) / 30.6001).floor
dom = b - d - (30.6001 * e).floor
if e <= 13
m = e - 1
y = c - 4716
else
m = e - 13
y = c - 4715
end
return y, m, dom
a = (y / 100.0).floor
b = 2 - a + (a / 4.0).floor
jd = (365.25 * (y + 4716)).floor +
(30.6001 * (m + 1)).floor +
d + b - 1524
if os?(jd, sg)
jd -= b
end
jd
end
def ordinal_to_jd(y, d, sg=GREGORIAN)
civil_to_jd(y, 1, d, sg)
def self.jd_to_civil(jd, sg=GREGORIAN)
if os?(jd, sg)
a = jd
else
x = ((jd - 1867216.25) / 36524.25).floor
a = jd + 1 + x - (x / 4.0).floor
end
def jd_to_ordinal(jd, sg=GREGORIAN)
y = jd_to_civil(jd, sg)[0]
doy = jd - civil_to_jd(y - 1, 12, 31, ns?(jd, sg))
return y, doy
b = a + 1524
c = ((b - 122.1) / 365.25).floor
d = (365.25 * c).floor
e = ((b - d) / 30.6001).floor
dom = b - d - (30.6001 * e).floor
if e <= 13
m = e - 1
y = c - 4716
else
m = e - 13
y = c - 4715
end
return y, m, dom
end
def jd_to_commercial(jd, sg=GREGORIAN)
def self.ordinal_to_jd(y, d, sg=GREGORIAN)
civil_to_jd(y, 1, d, sg)
end
def self.jd_to_ordinal(jd, sg=GREGORIAN)
y = jd_to_civil(jd, sg)[0]
doy = jd - civil_to_jd(y - 1, 12, 31, ns?(jd, sg))
return y, doy
end
def self.jd_to_commercial(jd, sg=GREGORIAN)
ns = ns?(jd, sg)
a = jd_to_civil(jd - 3, ns)[0]
y = if jd >= commercial_to_jd(a + 1, 1, 1, ns) then a + 1 else a end
w = 1 + (jd - commercial_to_jd(y, 1, 1, ns)) / 7
d = (jd + 1) % 7
if d.zero? then d = 7 end
return y, w, d
end
def self.commercial_to_jd(y, w, d, ns=GREGORIAN)
jd = civil_to_jd(y, 1, 4, ns)
(jd - (((jd - 1) + 1) % 7)) +
7 * (w - 1) +
(d - 1)
end
def self.clfloor(x, y=1)
q, r = x.divmod(y)
q = q.to_i
return q, r
end
def self.rjd_to_jd(rjd, of=0) clfloor(rjd + of + 1.to_r/2) end
def self.jd_to_rjd(jd, fr, of=0) jd + fr - of - 1.to_r/2 end
def self.day_fraction_to_time(fr)
h, fr = clfloor(fr, 1.to_r/24)
min, fr = clfloor(fr, 1.to_r/1440)
s, fr = clfloor(fr, 1.to_r/86400)
return h, min, s, fr
end
def self.time_to_day_fraction(h, min, s)
h.to_r/24 + min.to_r/1440 + s.to_r/86400
end
def self.mjd_to_jd(mjd) mjd + 4800001.to_r/2 end
def self.jd_to_mjd(jd) jd - 4800001.to_r/2 end
def self.tjd_to_jd(tjd) tjd + 4880001.to_r/2 end
def self.jd_to_tjd(jd) jd - 4880001.to_r/2 end
def self.tjd2_to_jd(cycle, tjd) tjd_to_jd(cycle * 10000 + tjd) end
def self.jd_to_tjd2(jd) clfloor(jd_to_tjd(jd), 10000) end
def self.ld_to_jd(ld) ld + 2299160 end
def self.jd_to_ld(jd) jd - 2299160 end
def self.jd_to_wday(jd) (jd + 1) % 7 end
def self.julian_leap? (y) y % 4 == 0 end
def self.gregorian_leap? (y) y % 4 == 0 and y % 100 != 0 or y % 400 == 0 end
class << self; alias_method :leap?, :gregorian_leap? end
class << self; alias_method :new0, :new end
def self.exist1? (jd, sg=ITALY) jd end
class << self; alias_method :valid_jd?, :exist1? end
def self.new1(jd=0, sg=ITALY)
jd = exist1?(jd, sg)
new0(jd_to_rjd(jd, 0, 0), 0, sg)
end
class << self; alias_method :jd, :new1 end
def self.exist2? (y, d, sg=ITALY)
if d < 0
ny, = clfloor(y + 1, 1)
jd = ordinal_to_jd(ny, d + 1, sg)
ns = ns?(jd, sg)
a = jd_to_civil(jd - 3, ns)[0]
y = if jd >= commercial_to_jd(a + 1, 1, 1, ns) then a + 1 else a end
w = 1 + (jd - commercial_to_jd(y, 1, 1, ns)) / 7
d = (jd + 1) % 7
if d.zero? then d = 7 end
return y, w, d
return unless [y] == jd_to_ordinal(jd, sg)[0..0]
return unless [ny, 1] == jd_to_ordinal(jd - d, ns)
else
jd = ordinal_to_jd(y, d, sg)
return unless [y, d] == jd_to_ordinal(jd, sg)
end
jd
end
def commercial_to_jd(y, w, d, ns=GREGORIAN)
jd = civil_to_jd(y, 1, 4, ns)
(jd - (((jd - 1) + 1) % 7)) +
7 * (w - 1) +
(d - 1)
class << self; alias_method :valid_ordinal?, :exist2? end
def self.new2(y=-4712, d=1, sg=ITALY)
unless jd = exist2?(y, d, sg)
raise ArgumentError, 'invalid date'
end
new0(jd_to_rjd(jd, 0, 0), 0, sg)
end
def clfloor(x, y=1)
q, r = x.divmod(y)
q = q.to_i
return q, r
class << self; alias_method :ordinal, :new2 end
def self.exist3? (y, m, d, sg=ITALY)
if m < 0
m += 13
end
def rjd_to_jd(rjd) clfloor(rjd + 0.5) end
def jd_to_rjd(jd, fr) jd + fr - 0.5 end
def mjd_to_jd(mjd) mjd + 2400000.5 end
def jd_to_mjd(jd) jd - 2400000.5 end
def tjd_to_jd(tjd) tjd + 2440000.5 end
def jd_to_tjd(jd) jd - 2440000.5 end
def tjd2_to_jd(cycle, tjd) tjd_to_jd(cycle * 10000 + tjd) end
def jd_to_tjd2(jd) clfloor(jd_to_tjd(jd), 10000) end
def ld_to_jd(ld) ld + 2299160 end
def jd_to_ld(jd) jd - 2299160 end
def jd_to_wday(jd) (jd + 1) % 7 end
def julian_leap? (y) y % 4 == 0 end
def gregorian_leap? (y) y % 4 == 0 and y % 100 != 0 or y % 400 == 0 end
alias_method :leap?, :gregorian_leap?
alias_method :new0, :new
def new1(jd=0, sg=ITALY) new0(jd, sg) end
def exist3? (y, m, d, sg=ITALY)
if m < 0
m += 13
end
if d < 0
ny, nm = clfloor(y * 12 + m, 12)
nm, = clfloor(nm + 1, 1)
jd = civil_to_jd(ny, nm, d + 1, sg)
ns = ns?(jd, sg)
return unless [y, m] == jd_to_civil(jd, sg)[0..1]
return unless [ny, nm, 1] == jd_to_civil(jd - d, ns)
else
jd = civil_to_jd(y, m, d, sg)
return unless [y, m, d] == jd_to_civil(jd, sg)
end
jd
if d < 0
ny, nm = clfloor(y * 12 + m, 12)
nm, = clfloor(nm + 1, 1)
jd = civil_to_jd(ny, nm, d + 1, sg)
ns = ns?(jd, sg)
return unless [y, m] == jd_to_civil(jd, sg)[0..1]
return unless [ny, nm, 1] == jd_to_civil(jd - d, ns)
else
jd = civil_to_jd(y, m, d, sg)
return unless [y, m, d] == jd_to_civil(jd, sg)
end
jd
end
alias_method :exist?, :exist3?
class << self; alias_method :exist?, :exist3? end
class << self; alias_method :valid_civil?, :exist3? end
def new3(y=-4712, m=1, d=1, sg=ITALY)
unless jd = exist3?(y, m, d, sg)
raise ArgumentError, 'invalid date'
end
new0(jd, sg)
def self.new3(y=-4712, m=1, d=1, sg=ITALY)
unless jd = exist3?(y, m, d, sg)
raise ArgumentError, 'invalid date'
end
new0(jd_to_rjd(jd, 0, 0), 0, sg)
end
alias_method :new, :new3
class << self; alias_method :new, :new3 end
class << self; alias_method :civil, :new3 end
def exist2? (y, d, sg=ITALY)
if d < 0
ny, = clfloor(y + 1, 1)
jd = ordinal_to_jd(ny, d + 1, sg)
ns = ns?(jd, sg)
return unless [y] == jd_to_ordinal(jd, sg)[0..0]
return unless [ny, 1] == jd_to_ordinal(jd - d, ns)
else
jd = ordinal_to_jd(y, d, sg)
return unless [y, d] == jd_to_ordinal(jd, sg)
end
jd
def self.existw? (y, w, d, sg=ITALY)
if d < 0
d += 8
end
def new2(y=-4712, d=1, sg=ITALY)
unless jd = exist2?(y, d, sg)
raise ArgumentError, 'invalid date'
end
new0(jd, sg)
if w < 0
w = jd_to_commercial(commercial_to_jd(y + 1, 1, 1) + w * 7)[1]
end
jd = commercial_to_jd(y, w, d)
return unless ns?(jd, sg)
return unless [y, w, d] == jd_to_commercial(jd)
jd
end
def existw? (y, w, d, sg=ITALY)
if d < 0
d += 8
end
if w < 0
w = jd_to_commercial(commercial_to_jd(y + 1, 1, 1) + w * 7)[1]
end
jd = commercial_to_jd(y, w, d)
return unless ns?(jd, sg)
return unless [y, w, d] == jd_to_commercial(jd)
jd
end
class << self; alias_method :valid_commercial?, :existw? end
def neww(y=1582, w=41, d=5, sg=ITALY)
unless jd = existw?(y, w, d, sg)
raise ArgumentError, 'invalid date'
end
new0(jd, sg)
def self.neww(y=1582, w=41, d=5, sg=ITALY)
unless jd = existw?(y, w, d, sg)
raise ArgumentError, 'invalid date'
end
new0(jd_to_rjd(jd, 0, 0), 0, sg)
end
def today(sg=ITALY)
new0(civil_to_jd(*(Time.now.to_a[3..5].reverse << sg)), sg)
class << self; alias_method :commercial, :neww end
def self.new_with_hash(elem, sg)
elem ||= {}
y, m, d = elem.select(:year, :mon, :mday)
if [y, m, d].include? nil
raise ArgumentError, 'invalid date'
else
new3(y, m, d, sg)
end
end
private_class_method :new_with_hash
def self.strptime(str='-4712-01-01', fmt='%F', sg=ITALY)
elem = _strptime(str, fmt)
new_with_hash(elem, sg)
end
def self.parse(str='-4712-01-01', comp=false, sg=ITALY)
elem = _parse(str, comp)
new_with_hash(elem, sg)
end
def self.today(sg=ITALY)
jd = civil_to_jd(*(Time.now.to_a[3..5].reverse << sg))
new0(jd_to_rjd(jd, 0, 0), 0, sg)
end
class << self
def once(*ids)
for id in ids
@ -212,7 +270,7 @@ class Date
end
def initialize(rjd=0, sg=ITALY) @rjd, @sg = rjd, sg end
def initialize(rjd=0, of=0, sg=ITALY) @rjd, @of, @sg = rjd, of, sg end
def rjd() @rjd end
def rmjd() type.jd_to_mjd(@rjd) end
@ -221,14 +279,14 @@ class Date
once :rmjd, :rtjd, :rtjd2
def jd() type.rjd_to_jd(@rjd)[0] end
def fr1() type.rjd_to_jd(@rjd)[1] end
def jd() type.rjd_to_jd(@rjd, @of)[0] end
def day_fraction() type.rjd_to_jd(@rjd, @of)[1] end
def mjd() type.jd_to_mjd(jd) end
def tjd() type.jd_to_tjd(jd) end
def tjd2() type.jd_to_tjd2(jd) end
def ld() type.jd_to_ld(jd) end
once :jd, :fr1, :mjd, :tjd, :tjd2, :ld
once :jd, :day_fraction, :mjd, :tjd, :tjd2, :ld
def civil() type.jd_to_civil(jd, @sg) end
def ordinal() type.jd_to_ordinal(jd, @sg) end
@ -240,13 +298,33 @@ class Date
def year() civil[0] end
def yday() ordinal[1] end
def mon() civil[1] end
alias_method :month, :mon
def mday() civil[2] end
alias_method :month, :mon
alias_method :day, :mday
def time() type.day_fraction_to_time(day_fraction) end
once :time
private :time
def hour() time[0] end
def min() time[1] end
def sec() time[2] end
def sec_fraction() time[3] end
private :hour, :min, :sec, :sec_fraction
def zone
['Z',
format('%+.2d%02d',
(of / (1.to_r/24)).to_i,
(of.abs % (1.to_r/24) / (1.to_r/1440)).to_i)
][of<=>0]
end
private :zone
def cwyear() commercial[0] end
def cweek() commercial[1] end
def cwday() commercial[2] end
@ -268,23 +346,34 @@ class Date
once :leap?
def sg() @sg end
def newsg(sg=type::ITALY) type.new0(@rjd, sg) end
def newsg(sg=type::ITALY) type.new0(@rjd, @of, sg) end
alias_method :start, :sg
alias_method :new_start, :newsg
def italy() newsg(type::ITALY) end
def england() newsg(type::ENGLAND) end
def julian() newsg(type::JULIAN) end
def gregorian() newsg(type::GREGORIAN) end
def of() @of end
def newof(of=0) type.new0(@rjd, of, @sg) end
alias_method :offset, :of
alias_method :new_offset, :newof
private :of, :newof, :offset, :new_offset
def + (n)
case n
when Numeric; return type.new0(@rjd + n, @sg)
when Numeric; return type.new0(@rjd + n, @of, @sg)
end
raise TypeError, 'expected numeric'
end
def - (x)
case x
when Numeric; return type.new0(@rjd - x, @sg)
when Numeric; return type.new0(@rjd - x, @of, @sg)
when Date; return @rjd - x.rjd
end
raise TypeError, 'expected numeric or date'
@ -334,12 +423,112 @@ class Date
alias_method :next, :succ
def eql? (other) Date === other and self == other end
def hash() type.clfloor(@rjd)[0] end
def hash() @rjd.hash end
def inspect() format('#<%s: %s,%s>', type, @rjd, @sg) end
def to_s() format('%.4d-%02d-%02d', year, mon, mday) end
def inspect() format('#<%s: %s,%s,%s>', type, @rjd, @of, @sg) end
def to_s() strftime end
def _dump(limit) Marshal.dump([@rjd, @sg], -1) end
def _dump(limit) Marshal.dump([@rjd, @of, @sg], -1) end
def self._load(str) new0(*Marshal.load(str)) end
end
class DateTime < Date
def self.existt? (h, min, s)
h += 24 if h < 0
min += 60 if min < 0
s += 60 if s < 0
return unless (0..24) === h and
(0..59) === min and
(0..59) === s
time_to_day_fraction(h, min, s)
end
class << self; alias_method :valid_time?, :existt? end
def self.new1(jd=0, h=0, min=0, s=0, of=0, sg=ITALY)
unless (jd = exist1?(jd, sg)) and
(fr = existt?(h, min, s))
raise ArgumentError, 'invalid date'
end
new0(jd_to_rjd(jd, fr, of), of, sg)
end
class << self; alias_method :jd, :new1 end
def self.new2(y=-4712, d=1, h=0, min=0, s=0, of=0, sg=ITALY)
unless (jd = exist2?(y, d, sg)) and
(fr = existt?(h, min, s))
raise ArgumentError, 'invalid date'
end
new0(jd_to_rjd(jd, fr, of), of, sg)
end
class << self; alias_method :ordinal, :new2 end
def self.new3(y=-4712, m=1, d=1, h=0, min=0, s=0, of=0, sg=ITALY)
unless (jd = exist3?(y, m, d, sg)) and
(fr = existt?(h, min, s))
raise ArgumentError, 'invalid date'
end
new0(jd_to_rjd(jd, fr, of), of, sg)
end
class << self; alias_method :new, :new3 end
class << self; alias_method :civil, :new3 end
def self.neww(y=1582, w=41, d=5, h=0, min=0, s=0, of=0, sg=ITALY)
unless (jd = existw?(y, w, d, sg)) and
(fr = existt?(h, min, s))
raise ArgumentError, 'invalid date'
end
new0(jd_to_rjd(jd, fr, of), of, sg)
end
class << self; alias_method :commercial, :neww end
def self.new_with_hash(elem, sg)
elem ||= {}
y, m, d, h, min, s, of =
elem.select(:year, :mon, :mday, :hour, :min, :sec, :offset)
h ||= 0
min ||= 0
s ||= 0
of ||= 0
if [y, m, d].include? nil
raise ArgumentError, 'invalid date'
else
new3(y, m, d, h, min, s, of.to_r/86400, sg)
end
end
private_class_method :new_with_hash
def self.strptime(str='-4712-01-01T00:00:00Z', fmt='%FT%T%Z', sg=ITALY)
elem = _strptime(str, fmt)
new_with_hash(elem, sg)
end
def self.parse(str='-4712-01-01T00:00:00Z', comp=false, sg=ITALY)
elem = _parse(str, comp)
new_with_hash(elem, sg)
end
class << self; undef_method :today end
def self.now(sg=ITALY)
i = Time.now
a = i.to_a[0..5].reverse
jd = civil_to_jd(*(a[0,3] << sg))
fr = time_to_day_fraction(*(a[3,3])) + i.usec.to_r/86400000000
d = Time.gm(*i.to_a).to_i - i.to_i
d += d / d.abs if d.nonzero?
of = (d / 60).to_r/1440
new0(jd_to_rjd(jd, fr, of), of, sg)
end
public :hour, :min, :sec, :sec_fraction, :zone,
:of, :newof, :offset, :new_offset
end

529
lib/date/format.rb Normal file
View File

@ -0,0 +1,529 @@
# format.rb: Written by Tadayoshi Funaba 1999-2002
# $Id: format.rb,v 2.7 2002-05-17 21:20:28+09 tadf Exp $
class Date
MONTHS = {
'january' => 1, 'february' => 2, 'march' => 3, 'april' => 4,
'may' => 5, 'june' => 6, 'july' => 7, 'august' => 8,
'september'=> 9, 'october' =>10, 'november' =>11, 'december' =>12
}
DAYS = {
'sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday'=> 3,
'thursday' => 4, 'friday' => 5, 'saturday' => 6
}
ABBR_MONTHS = {
'jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4,
'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8,
'sep' => 9, 'oct' =>10, 'nov' =>11, 'dec' =>12
}
ABBR_DAYS = {
'sun' => 0, 'mon' => 1, 'tue' => 2, 'wed' => 3,
'thu' => 4, 'fri' => 5, 'sat' => 6
}
ZONES = {
'ut' => 0*3600, 'gmt' => 0*3600, 'est' => -5*3600, 'edt' => -4*3600,
'cst' => -6*3600, 'cdt' => -5*3600, 'mst' => -7*3600, 'mdt' => -6*3600,
'pst' => -8*3600, 'pdt' => -7*3600,
'a' => 1*3600, 'b' => 2*3600, 'c' => 3*3600, 'd' => 4*3600,
'e' => 5*3600, 'f' => 6*3600, 'g' => 7*3600, 'h' => 8*3600,
'i' => 9*3600, 'k' => 10*3600, 'l' => 11*3600, 'm' => 12*3600,
'n' => -1*3600, 'o' => -2*3600, 'p' => -3*3600, 'q' => -4*3600,
'r' => -5*3600, 's' => -6*3600, 't' => -7*3600, 'u' => -8*3600,
'v' => -9*3600, 'w' =>-10*3600, 'x' =>-11*3600, 'y' =>-12*3600,
'z' => 0*3600,
'utc' => 0*3600, 'wet' => 0*3600, 'bst' => 1*3600, 'wat' => -1*3600,
'at' => -2*3600, 'ast' => -4*3600, 'adt' => -3*3600, 'yst' => -9*3600,
'ydt' => -8*3600, 'hst' =>-10*3600, 'hdt' => -9*3600, 'cat' =>-10*3600,
'ahst'=>-10*3600, 'nt' =>-11*3600, 'idlw'=>-12*3600, 'cet' => 1*3600,
'met' => 1*3600, 'mewt'=> 1*3600, 'mest'=> 2*3600, 'mesz'=> 2*3600,
'swt' => 1*3600, 'sst' => 2*3600, 'fwt' => 1*3600, 'fst' => 2*3600,
'eet' => 2*3600, 'bt' => 3*3600, 'zp4' => 4*3600, 'zp5' => 5*3600,
'zp6' => 6*3600, 'wast'=> 7*3600, 'wadt'=> 8*3600, 'cct' => 8*3600,
'jst' => 9*3600, 'east'=> 10*3600, 'eadt'=> 11*3600, 'gst' => 10*3600,
'nzt' => 12*3600, 'nzst'=> 12*3600, 'nzdt'=> 13*3600, 'idle'=> 12*3600
}
def self.__strptime(str, fmt, elem)
fmt.scan(/%[EO]?.|./o) do |c|
cc = c.sub(/\A%[EO]?(.)\Z/o, '%\\1')
case cc
when /\A\s/o
str.sub!(/\A[\s\v]+/o, '')
when '%A', '%a'
return unless str.sub!(/\A([a-z]+)\b/io, '')
val = DAYS[$1.downcase] || ABBR_DAYS[$1.downcase]
return unless val
elem[:wday] = val
when '%B', '%b', '%h'
return unless str.sub!(/\A([a-z]+)\b/io, '')
val = MONTHS[$1.downcase] || ABBR_MONTHS[$1.downcase]
return unless val
elem[:mon] = val
when '%C'
return unless str.sub!(/\A(\d+)/o, '')
val = $1.to_i
elem[:cent] = val
when '%c'
return unless __strptime(str, '%a %b %e %H:%M:%S %Y', elem)
when '%D'
return unless __strptime(str, '%m/%d/%y', elem)
when '%d', '%e'
return unless str.sub!(/\A ?(\d+)/o, '')
val = $1.to_i
return unless (1..31) === val
elem[:mday] = val
when '%F'
return unless __strptime(str, '%Y-%m-%d', elem)
when '%G'
return unless str.sub!(/\A([-+]?\d+)/o, '')
val = $1.to_i
elem[:cwyear] = val
when '%g'
return unless str.sub!(/\A(\d+)/o, '')
val = $1.to_i
return unless (0..99) === val
elem[:cwyear] = val
elem[:cent] ||= if val >= 69 then 19 else 20 end
when '%H', '%k'
return unless str.sub!(/\A ?(\d+)/o, '')
val = $1.to_i
return unless (0..24) === val
elem[:hour] = val
when '%I', '%l'
return unless str.sub!(/\A ?(\d+)/o, '')
val = $1.to_i
return unless (1..12) === val
elem[:hour] = val
when '%j'
return unless str.sub!(/\A(\d+)/o, '')
val = $1.to_i
return unless (1..366) === val
elem[:yday] = val
when '%M'
return unless str.sub!(/\A(\d+)/o, '')
val = $1.to_i
return unless (0..59) === val
elem[:min] = val
when '%m'
return unless str.sub!(/\A(\d+)/o, '')
val = $1.to_i
return unless (1..12) === val
elem[:mon] = val
when '%n'
return unless __strptime(str, ' ', elem)
when '%p', '%P'
return unless str.sub!(/\A([ap])(?:m\b|\.m\.)/io, '')
elem[:merid] = if $1.downcase == 'a' then 0 else 12 end
when '%R'
return unless __strptime(str, '%H:%M', elem)
when '%r'
return unless __strptime(str, '%I:%M:%S %p', elem)
when '%S'
return unless str.sub!(/\A(\d+)/o, '')
val = $1.to_i
return unless (0..60) === val
elem[:sec] = val
when '%s'
return unless str.sub!(/\A(\d+)/o, '')
val = $1.to_i
elem[:seconds] = val
when '%T'
return unless __strptime(str, '%H:%M:%S', elem)
when '%t'
return unless __strptime(str, ' ', elem)
when '%U', '%W'
return unless str.sub!(/\A(\d+)/o, '')
val = $1.to_i
return unless (0..53) === val
elem[if c == '%U' then :wnum0 else :wnum1 end] = val
when '%u'
return unless str.sub!(/\A(\d+)/o, '')
val = $1.to_i
return unless (1..7) === val
elem[:cwday] = val
when '%V'
return unless str.sub!(/\A(\d+)/o, '')
val = $1.to_i
return unless (1..53) === val
elem[:cweek] = val
when '%v'
return unless __strptime(str, '%e-%b-%Y', elem)
when '%w'
return unless str.sub!(/\A(\d+)/o, '')
val = $1.to_i
return unless (0..6) === val
elem[:wday] = val
when '%X'
return unless __strptime(str, '%H:%M:%S', elem)
when '%x'
return unless __strptime(str, '%m/%d/%y', elem)
when '%Y'
return unless str.sub!(/\A([-+]?\d+)/o, '')
val = $1.to_i
elem[:year] = val
when '%y'
return unless str.sub!(/\A(\d+)/o, '')
val = $1.to_i
return unless (0..99) === val
elem[:year] = val
elem[:cent] ||= if val >= 69 then 19 else 20 end
when '%Z', '%z'
return unless str.sub!(/\A([a-z0-9:+-]+(?:\s+dst\b)?)/io, '')
val = $1
elem[:zone] = val
offset = zone_to_diff(val)
elem[:offset] = offset
when '%%'
return unless str.sub!(/\A%/o, '')
when '%+'
return unless __strptime(str, '%a %b %e %H:%M:%S %Z %Y', elem)
when '%1'
return unless str.sub!(/\A(\d+)/o, '')
val = $1.to_i
elem[:jd] = val
when '%2'
return unless __strptime(str, '%Y-%j', elem)
when '%3'
return unless __strptime(str, '%F', elem)
else
return unless str.sub!(Regexp.new('\\A' + Regexp.quote(c)), '')
end
end
if cent = elem.delete(:cent)
if elem[:cwyear]
elem[:cwyear] += cent * 100
end
if elem[:year]
elem[:year] += cent * 100
end
end
if merid = elem.delete(:merid)
if elem[:hour]
elem[:hour] %= 12
elem[:hour] += merid
end
end
str
end
private_class_method :__strptime
def self._strptime(str, fmt='%F')
elem = {}
elem if __strptime(str.dup, fmt, elem)
end
PARSE_MONTHPAT = ABBR_MONTHS.keys.join('|')
PARSE_DAYPAT = ABBR_DAYS. keys.join('|')
def self._parse(str, comp=false)
str = str.dup
str.gsub!(/[^-+.\/:0-9a-z]+/ino, ' ')
# day
if str.sub!(/(#{PARSE_DAYPAT})\S*/ino, ' ')
wday = ABBR_DAYS[$1.downcase]
end
# time
if str.sub!(
/(\d+):(\d+)(?::(\d+))?
(?:
\s*
([ap])(?:m\b|\.m\.)
)?
(?:
\s*
(
[a-z]+(?:\s+dst)?\b
|
[-+]\d+(?::?\d+)
)
)?
/inox,
' ')
hour = $1.to_i
min = $2.to_i
sec = $3.to_i if $3
if $4
hour %= 12
if $4.downcase == 'p'
hour += 12
end
end
zone = $5
end
# eu
if str.sub!(
/(\d+)\S*
\s+
(#{PARSE_MONTHPAT})\S*
(?:
\s+
(-?\d+)
)?
/inox,
' ')
mday = $1.to_i
mon = ABBR_MONTHS[$2.downcase]
if $3
year = $3.to_i
if $3.size > 2
comp = false
end
end
# us
elsif str.sub!(
/(#{PARSE_MONTHPAT})\S*
\s+
(\d+)\S*
(?:
\s+
(-?\d+)
)?
/inox,
' ')
mon = ABBR_MONTHS[$1.downcase]
mday = $2.to_i
if $3
year = $3.to_i
if $3.size > 2
comp = false
end
end
# iso
elsif str.sub!(/([-+]?\d+)-(\d+)-(-?\d+)/no, ' ')
year = $1.to_i
mon = $2.to_i
mday = $3.to_i
if $1.size > 2
comp = false
elsif $3.size > 2
comp = false
mday, mon, year = year, mon, mday
end
# jis
elsif str.sub!(/([MTSH])(\d+)\.(\d+)\.(\d+)/no, ' ')
e = { 'M'=>1867,
'T'=>1911,
'S'=>1925,
'H'=>1988
}[$1]
year = $2.to_i + e
mon = $3.to_i
mday = $4.to_i
# vms
elsif str.sub!(/(-?\d+)-(#{PARSE_MONTHPAT})[^-]*-(-?\d+)/ino, ' ')
mday = $1.to_i
mon = ABBR_MONTHS[$2.downcase]
year = $3.to_i
if $1.size > 2
comp = false
year, mon, mday = mday, mon, year
elsif $3.size > 2
comp = false
end
# sla
elsif str.sub!(%r|(-?\d+)/(\d+)(?:/(-?\d+))?|no, ' ')
mon = $1.to_i
mday = $2.to_i
if $3
year = $3.to_i
if $3.size > 2
comp = false
end
end
if $1.size > 2
comp = false
year, mon, mday = mon, mday, year
end
# ddd
elsif str.sub!(
/([-+]?)(\d{4,14})
(?:
\s*
T?
\s*
(\d{2,6})
)?
(?:
\s*
(
Z
|
[-+]\d{2,4}
)
\b
)?
/nox,
' ')
case $2.size
when 4
mon = $2[ 0, 2].to_i
mday = $2[ 2, 2].to_i
when 6
year = ($1 + $2[ 0, 2]).to_i
mon = $2[ 2, 2].to_i
mday = $2[ 4, 2].to_i
when 8, 10, 12, 14
year = ($1 + $2[ 0, 4]).to_i
mon = $2[ 4, 2].to_i
mday = $2[ 6, 2].to_i
hour = $2[ 8, 2].to_i if $2.size >= 10
min = $2[10, 2].to_i if $2.size >= 12
sec = $2[12, 2].to_i if $2.size >= 14
comp = false
end
if $3
case $3.size
when 2, 4, 6
hour = $3[ 0, 2].to_i
min = $3[ 2, 2].to_i if $3.size >= 4
sec = $3[ 4, 2].to_i if $3.size >= 6
end
end
zone = $4
end
if comp and year
if year >= 0 and year <= 99
if year >= 69
year += 1900
else
year += 2000
end
end
end
elem = {}
elem[:year] = year if year
elem[:mon] = mon if mon
elem[:mday] = mday if mday
elem[:hour] = hour if hour
elem[:min] = min if min
elem[:sec] = sec if sec
elem[:zone] = zone if zone
offset = zone_to_diff(zone) if zone
elem[:offset] = offset if offset
elem[:wday] = wday if wday
elem
end
def self.zone_to_diff(str)
abb, dst = str.downcase.split(/\s+/o, 2)
if ZONES.include?(abb)
offset = ZONES[abb]
offset += 3600 if dst
elsif /\A([+-])(\d{2}):?(\d{2})?\Z/no =~ str
offset = $2.to_i * 3600 + $3.to_i * 60
offset *= -1 if $1 == '-'
end
offset
end
def strftime(fmt='%F')
o = ''
fmt.scan(/%[EO]?.|./o) do |c|
cc = c.sub(/^%[EO]?(.)$/o, '%\\1')
case cc
when '%A'; o << DAYNAMES[wday]
when '%a'; o << ABBR_DAYNAMES[wday]
when '%B'; o << MONTHNAMES[mon]
when '%b'; o << ABBR_MONTHNAMES[mon]
when '%C'; o << '%02d' % (year / 100.0).floor # P2,ID
when '%c'; o << strftime('%a %b %e %H:%M:%S %Y')
when '%D'; o << strftime('%m/%d/%y') # P2,ID
when '%d'; o << '%02d' % mday
when '%e'; o << '%2d' % mday
when '%F'; o << strftime('%Y-%m-%d') # ID
when '%G'; o << '%.4d' % cwyear # ID
when '%g'; o << '%02d' % (cwyear % 100) # ID
when '%H'; o << '%02d' % hour
when '%h'; o << strftime('%b') # P2,ID
when '%I'; o << '%02d' % ((hour % 12).nonzero? or 12)
when '%j'; o << '%03d' % yday
when '%k'; o << '%2d' % hour # AR,TZ,GL
when '%l'; o << '%2d' % ((hour % 12).nonzero? or 12) # AR,TZ,GL
when '%M'; o << '%02d' % min
when '%m'; o << '%02d' % mon
when '%n'; o << "\n" # P2,ID
when '%P'; o << if hour < 12 then 'am' else 'pm' end # GL
when '%p'; o << if hour < 12 then 'AM' else 'PM' end
when '%R'; o << strftime('%H:%M') # ID
when '%r'; o << strftime('%I:%M:%S %p') # P2,ID
when '%S'; o << '%02d' % sec
when '%s' # TZ,GL
d = rjd - type.jd_to_rjd(type.civil_to_jd(1970,1,1), 0)
s = (d * 86400).to_i
o << '%d' % s
when '%T'; o << strftime('%H:%M:%S') # P2,ID
when '%t'; o << "\t" # P2,ID
when '%U', '%W'
a = type.civil_to_jd(year, 1, 1, ns?) + 6
k = if c == '%U' then 0 else 1 end
w = (jd - (a - ((a - k) + 1) % 7) + 7) / 7
o << '%02d' % w
when '%u'; o << '%d' % cwday # P2,ID
when '%V'; o << '%02d' % cweek # P2,ID
when '%v'; o << strftime('%e-%b-%Y') # AR,TZ
when '%w'; o << '%d' % wday
when '%X'; o << strftime('%H:%M:%S')
when '%x'; o << strftime('%m/%d/%y')
when '%Y'; o << '%.4d' % year
when '%y'; o << '%02d' % (year % 100)
when '%Z'; o << zone
when '%z'; o << zone # ID
when '%%'; o << '%'
when '%+'; o << strftime('%a %b %e %H:%M:%S %Z %Y') # TZ
when '%1'; o << '%d' % jd
when '%2'; o << strftime('%Y-%j')
when '%3'; o << strftime('%Y-%m-%d')
else; o << c
end
end
o
end
# alias_method :format, :strftime
def asctime() strftime('%c') end
alias_method :ctime, :asctime
end
class DateTime < Date
def self._strptime(str, fmt='%FT%T%Z')
super(str, fmt)
end
def strftime(fmt='%FT%T%Z')
super(fmt)
end
end

View File

@ -1,179 +1,13 @@
# parsedate3.rb: Written by Tadayoshi Funaba 2000, 2001
# $Id: parsedate3.rb,v 1.3 2001-01-18 12:09:47+09 tadf Exp $
# parsedate.rb: Written by Tadayoshi Funaba 2001, 2002
# $Id: parsedate.rb,v 2.6 2002-05-14 07:43:18+09 tadf Exp $
require 'date/format'
module ParseDate
MONTHS = {
'jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4,
'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8,
'sep' => 9, 'oct' =>10, 'nov' =>11, 'dec' =>12
}
MONTHPAT = MONTHS.keys.join('|')
DAYS = {
'sun' => 0, 'mon' => 1, 'tue' => 2, 'wed' => 3,
'thu' => 4, 'fri' => 5, 'sat' => 6
}
DAYPAT = DAYS.keys.join('|')
def parsedate(date, cyear=false)
date = date.dup
# day
if date.sub!(/(#{DAYPAT})\S*/ino, ' ')
wday = DAYS[$1.downcase]
end
# time
if date.sub!(
/(\d+):(\d+)(?::(\d+))?
(?:
\s*
([ap])\.?m\.?
\b
)?
(?:
\s*
(
[a-z]+(?:\s+dst)?
|
[-+]\d+(?::?\d+)
)
\b
)?
/inox,
' ')
hour = $1.to_i
min = $2.to_i
sec = $3.to_i if $3
if $4
hour %= 12
if $4.downcase == 'p'
hour += 12
end
end
zone = $5
end
# eu
if date.sub!(
/(\d+)\S*
\s+
(#{MONTHPAT})\S*
(?:
\s+
(\d+)
)?
/inox,
' ')
mday = $1.to_i
mon = MONTHS[$2.downcase]
year = $3.to_i if $3
# us
elsif date.sub!(
/(#{MONTHPAT})\S*
\s+
(\d+)\S*
(?:
\s+
(\d+)
)?
/inox,
' ')
mon = MONTHS[$1.downcase]
mday = $2.to_i
year = $3.to_i if $3
# iso
elsif date.sub!(/(\d+)-(\d+)-(\d+)/no, ' ')
year = $1.to_i
mon = $2.to_i
mday = $3.to_i
mday, mon, year = year, mon, mday if $3.size >= 4
# jis
elsif date.sub!(/([MTSH])(\d+)\.(\d+)\.(\d+)/no, ' ')
e = { 'M'=>1867,
'T'=>1911,
'S'=>1925,
'H'=>1988
}[$1]
year, mon, mday = $2.to_i + e, $3.to_i, $4.to_i
# vms
elsif date.sub!(/(\d+)-(#{MONTHPAT})\S*-(\d+)/ino, ' ')
mday = $1.to_i
mon = MONTHS[$2.downcase]
year = $3.to_i
year, mon, mday = mday, mon, year if $1.size >= 4
# sla
elsif date.sub!(%r|(\d+)/(\d+)(?:/(\d+))?|no, ' ')
mon = $1.to_i
mday = $2.to_i
year = $3.to_i if $3
year, mon, mday = mon, mday, year if $1.size >= 4
# ddd
elsif date.sub!(
/(\d{4,14})
(?:
\s*
T?
\s*
(\d{2,6})
)?
(?:
\s*
(
Z
|
[-+]\d{2,4}
)
\b
)?
/nox,
' ')
case $1.size
when 4
mon = $1[ 0, 2].to_i
mday = $1[ 2, 2].to_i
when 6
year = $1[ 0, 2].to_i
mon = $1[ 2, 2].to_i
mday = $1[ 4, 2].to_i
when 8, 10, 12, 14
year = $1[ 0, 4].to_i
mon = $1[ 4, 2].to_i
mday = $1[ 6, 2].to_i
hour = $1[ 8, 2].to_i if $1.size >= 10
min = $1[10, 2].to_i if $1.size >= 12
sec = $1[12, 2].to_i if $1.size >= 14
end
if $2
case $2.size
when 2, 4, 6
hour = $2[ 0, 2].to_i
min = $2[ 2, 2].to_i if $2.size >= 4
sec = $2[ 4, 2].to_i if $2.size >= 6
end
end
zone = $3
end
if cyear and year
if year < 100
if year >= 69
year += 1900
else
year += 2000
end
end
end
return year, mon, mday, hour, min, sec, zone, wday
def parsedate(str, comp=false)
Date._parse(str, comp).
indexes(:year, :mon, :mday, :hour, :min, :sec, :zone, :wday)
end
module_function :parsedate

View File

@ -1,9 +1,9 @@
#! /usr/bin/env ruby
# cal.rb: Written by Tadayoshi Funaba 1998-2000
# $Id: cal.rb,v 1.11 2000-07-16 10:28:50+09 tadf Exp $
# cal.rb: Written by Tadayoshi Funaba 1998-2002
# $Id: cal.rb,v 2.3 2002-05-14 07:43:39+09 tadf Exp $
require 'date2'
require 'date'
require 'getopts'
$tab =
@ -84,7 +84,7 @@ end
usage unless getopts('jmty', "c:#{$cc}")
y, m = ARGV.indexes(1, 0).compact.collect{|x| x.to_i}
y, m = ARGV.select(1, 0).compact.collect{|x| x.to_i}
$OPT_y ||= (y and not m)
to = Date.today

View File

@ -3,7 +3,7 @@
# goodfriday.rb: Written by Tadayoshi Funaba 1998, 2000
# $Id: goodfriday.rb,v 1.1.1.1 2000-07-16 10:25:30+09 tadf Exp $
require 'date2'
require 'date'
def easter(y)
g = (y % 19) + 1