"Richard A. Ryan" <Richard.A.Ryan@noaa.gov> writes:
Hi,
I've tried this for ruby 1.8.1 and 1.6.8.
irb(main):001:0> Time.local(30, 15, 11, nil, nil, 2004, nil, 203, nil, nil)
=> Thu Jan 01 11:15:30 GMT 2004
For the 203rd day of the year, it does not seem I should be getting Jan 1.
Is this a bug?
No, it's a feature. That method call ultimately results in a call to the
system library function mktime(3), which ignores that field:
The function ignores the specified contents of
the structure members tm_wday and tm_yday and recomputes
them from the other information in the broken‐down time
structure.
Unfortunately, Ruby interferes with the autonormalization feature mktime(3)
provides: when calling mktime(3) directly, you can ask for, e.g. "January
203rd" and it will return the date of the 203rd day of the year. The Ruby
Time module won't let you do that, because it does a bounds check on the
arguments, so you have to do something else. One alternative is to use the
fact that you can do math on Time objects, which when treated as numbers
become a count of seconds (since January 1, 1970 at midnight UTC). So
to get the date of the 203rd day of 2004, you could do this:
irb(main):001:0> Time.local(30, 15, 11, 31, 12, 2003, nil, nil, nil, nil) + 203 * 86400
=> Wed Jul 21 12:15:30 EDT 2004
86400 is the number of seconds in a day, 24 x 60 x 60. To get the 203rd day of
2004, I asked for the last day of 2003 (Dec 31st) plus 203 days.
Oh, and the time came out 12:15 instead of 11:15 because of the switch to
daylight savings time; 24 hours after 11:15 on the day of the change to
EDT, it's 12:15. If you don't care about the time, you can use the 3-argument form of
Time.local, which uses the ISO order of year, month, day:
irb(main):002:0> Time.local(2003, 12, 31) + 203 * 86400
=> Wed Jul 21 01:00:00 EDT 2004
-Mark