DateTime.parse error on win32 (long timezone names)

W

Will Rogers

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:in `parse'
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,189
Members
46,735
Latest member
HikmatRamazanov

Latest Threads

Top