DateTime.parse error on win32 (long timezone names)

NOTE: this is a cross-post from comp.lang.ruby, because I don’t think
anyone read that message, which I posted about two months ago.

The date parsing code in the Ruby stdlib (date/format.rb) does not parse
strings with long timezones, e.g. “Eastern Daylight Time”, as opposed to
the abbreviated “EDT”. On win32, Time#to_s produces a string with the
long timezone name. So, Time.parse(Time.now.to_s) assumes the current
year, and DateTime.parse(Time.now.to_s) throws an error.

This is a critical issue for me because it is causing crashes in a
production Rails application during XML serialization in
ActionWebService.

For example:

irb(main):012:0> Time.now.to_s
=> “Tue May 16 09:27:36 Eastern Daylight Time 2006”
irb(main):013:0> Time.parse Time.now.to_s
=> Tue May 16 09:27:46 Eastern Daylight Time 2006
irb(main):014:0> Time.parse ‘Mon May 16 09:27:46 Eastern Daylight Time
2005’
=> Tue May 16 09:27:46 Eastern Daylight Time 2006
irb(main):001:0> Date._parse Time.now.to_s
=> {:hour=>10, :wday=>2, :mday=>16, :mon=>5, :zone=>“Eastern”,
:sec=>13, :min=>8}
irb(main):015:0> DateTime.parse Time.now.to_s
ArgumentError: 3 elements of civil date are necessary
from c:/ruby/lib/ruby/1.8/date.rb:1214:in new_with_hash' from c:/ruby/lib/ruby/1.8/date.rb:1258:inparse’
from (irb):15

(note the change of year from 2005 -> 2006 in lines 5 -> 6)

H:>ruby -v
ruby 1.8.4 (2005-12-24) [i386-mswin32]

There was a previous mention of this problem here, and Ara Howard
indicated that it was fixed in 1.9:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/161521

However, since his example “works” in 1.8.4 also, because of the year
assumption demonstrated above, I am inclined to think that it actually
is not fixed, and Ara’s example is a false positive, so to speak.

The fact that I was unable to find any revisions in the official Ruby
CVS addressing this problem reinforces that conclusion. If anyone knows
for sure whether this has been fixed or not, please point me to the
specific revision(s) in CVS.

I believe the relevant code is this regexp, beginning at
date/format.rb:261.

if str.sub!(
            /(\d+):(\d+)
             (?:
               :(\d+)(?:[,.](\d*))?
             )?
             (?:
               \s*
               ([ap])(?:m\b|\.m\.)
             )?
             (?:
               \s*
               (
                 [a-z]+(?:\s+dst)?\b
               |
                 [-+]\d+(?::?\d+)
               )
             )?
            /inox,
            ' ')

You can see how in the last group, [a-z]+(?:\s+dst)?\b will match “EDT”
or “Eastern” (as in the example above), but not “Eastern Standard Time”.
But, I am hardly familiar with the inner workings of the Ruby stdlib, so
I could be wrong. If anyone who knows more could take a look at this,
it would be much appreciated.

  • Will

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs