Mark J. Reed
10/13/2003 1:50:00 PM
I seem to have found a bug in the DateTime class's determination
of the local time zone. This one-liner demonstrates the problem:
$ ruby -rdate -e 'puts Time.now, DateTime.now'
Mon Oct 13 09:18:14 EDT 2003
2003-10-13T09:18:14-0501
The two classes agree on the local time, but not on the time zone;
EDT (United States' Eastern Daylight Time) is 4 hours earlier than
UTC (-0400); if you ignore daylight savings, we're 5 hours earlier than
UTC (-0500). So where is that extra minute coming from? It's almost as if
the logic were trying to adjust for daylight savings time, but doing so in
the wrong direction and in units of minutes instead of hours.
The only way I have so far discovered to get UTC out of a DateTime is via
DateTime#ajd, which returns the the Astronomical Julian Day number, but that's
enough to verify the one-minute offset. The Julian Day of the
UNIX epoch (1970 Jan 1 00:00:00 UTC) is 2,440,587.5, so I can get the
Julian Day for any given UNIX time_t value (such as the one returned
by Time#to_i) by simply dividing by the number of seconds in a day
(86,400) and adding the epochal JD:
irb(main):001:0> require 'date'
irb(main):002:0> t=Time.now, dt=DateTime.now
irb(main):003:0> puts 2_440_587.5 + Rational(t.to_i, 86_400).to_f, dt.ajd.to_f
2452926.0543287
2452926.0550290
Note the difference - 0.0007003 day, which is 60.5 seconds - one minute
plus a half second, which was probably the elapsed time between the
creation of the two objects (although that seems like an awfully long time
for that operation).
Looking at the source for DateTime::now:
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_ajd(jd, fr, of), of, sg)
end
The problem seems to be the sixth line:
d += d / d.abs if d.nonzero?
Which automatically increases the timezone offset by one minute, with
no indication as to why. Can someone (Mr. Tadayoshi Funaba, or
William Webber, are you out there?) perhaps shed some light on this
matter?
-Mark