[repost w/ minor corrections]
Hi folks,
While doing some WMI stuff in Ruby, I noticed that my datetimes were
getting all messed up. A brief inspection showed that the ddd parser
in Date._parse was missing the UTC offset for the CIM datetimes that
MS uses for WMI (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/date_and_time_format.asp).
Adding support for the WMI datetime format in Date._parse (and thusly
Time.parse via ParseDate.parsedate) is a snap, but it looks like the
Ruby date/time system is unable to gracefully handle cases where an
offset is specified with a number instead of a region (EST, EDT, etc).
Date._parse parses them, but ParseDate just (incorrectly, I think)
drops them without consideration.
ex:
#!/usr/bin/ruby
require 'Time’
require ‘Date’
now = Time.now
s1 = now.strftime(’%Y%m%d%H%M%S.000000-240’) #pretend we’re on the
east coast
s2 = now.strftime(’%Y%m%d%H%M%S.000000-360’) #pretend we’re on the
west coast
p Date._parse(s1) #{:hour=>14, :mday=>26, :offset=>-14400, :min=>37,
:mon=>4, :sec=>35, :year=>2004} (correct)
p Date._parse(s2) #{:hour=>14, :mday=>26, :offset=>-21600, :min=>37,
:mon=>4, :sec=>35, :year=>2004} (correct)
p Date._parse(s1) == Date._parse(s2) #false (correct)
p Time.parse(s1) #Mon Apr 26 14:37:35 Eastern Daylight Time 2004 (The
offset was ignored on both of these)
p Time.parse(s2) #Mon Apr 26 14:37:35 Eastern Daylight Time 2004
(inputs - the EDT is for my local tz )
p Time.parse(s1) == Time.parse(s2) #true (definitely not correct)
The obvious workaround is to convert all times to machine local time
when parsing them in Date._parse, but I don’t like losing that
information to the classes that properly handle the offset and call
_parse directly (like DateTime). Am I missing something, or is this a
problem?
Thanks,
Prs
p.s. sorry for my awful formatting.
ruby 1.8.0 (2003-08-04) [i386-mswin32]
+++ format.rb
@@ -361,6 +361,28 @@
year, mon, mday = mon, mday, year
end
-
MS WMI CIM datetimes
(ms-help://MS.VSCC/MS.MSDNVS/wmisdk/r_mof_3ovo.htm)
- #yyyymmddHHMMSS.mmmmmmsUUU
- elsif str.sub!(/([\d*]{4})([\d*]{2})([\d*]{2})([\d*]{2})([\d*]{2})([\d*]{2}).[\d*]{6}([-+])([\d]{3})/no,’
’) - year = $1.to_i if $1 != ‘*’ * 4
- mon = $2.to_i if $1 != ‘*’ * 2
- mday = $3.to_i if $1 != ‘*’ * 2
- hour = $4.to_i if $1 != ‘*’ * 2
- min = $5.to_i if $1 != ‘*’ * 2
- sec = $6.to_i if $1 != ‘*’ * 2
- offset = 60*($7+$8).to_i if $7 != ‘’ and $8 != '’ * 3
- comp = false
-
MS WMI CIM datetimes
(ms-help://MS.VSCC/MS.MSDNVS/wmisdk/r_mof_3ovo.htm)
- #yyyy-mm-dd HH:MM:SS:mmm
- elsif str.sub!(/([\d*]{4})-([\d*]{2})-([\d*]{2})\s([\d*]{2}):([\d*]{2}):([\d*]{2}):[\d*]{3}/no,’
’) - year = $1.to_i if $1 != ‘*’ * 4
- mon = $2.to_i if $1 != ‘*’ * 2
- mday = $3.to_i if $1 != ‘*’ * 2
- hour = $4.to_i if $1 != ‘*’ * 2
- min = $5.to_i if $1 != ‘*’ * 2
- sec = $6.to_i if $1 != ‘*’ * 2
- comp = false
···
-
ddd
elsif str.sub!(
/([-+]?)(\d{4,14})