Date.parse('17:26:33 Oct 31, 2009') returns invalid date

Hi,

For some reason ruby 1.8.6 return invalid date exception when parsing a
date of Oct 31 (yesterday) in the format above. Oct 30 and most other
dates parses fine and run fine. Time, year or timezone don’t matter.

On 2009-11-01, Jacob G. [email protected] wrote:

For some reason ruby 1.8.6 return invalid date exception when parsing a
date of Oct 31 (yesterday) in the format above. Oct 30 and most other
dates parses fine and run fine. Time, year or timezone don’t matter.

It’s suspiciously close to a range where you would be in a daylight
savings crossover in at least one timezone, but unless that’s it, I
can’t suggest anything.

-s

Seebs wrote:

On 2009-11-01, Jacob G. [email protected] wrote:

For some reason ruby 1.8.6 return invalid date exception when parsing a
date of Oct 31 (yesterday) in the format above. Oct 30 and most other
dates parses fine and run fine. Time, year or timezone don’t matter.

It’s suspiciously close to a range where you would be in a daylight
savings crossover in at least one timezone, but unless that’s it, I
can’t suggest anything.

-s

I don’t know why this should matter. It’s bug still.

I’ve now figured out that an explicit
DateTime.strptime(‘17:26:33 Oct 31, 2009 PST’, ‘%T %b %d, %Y %Z’)
will work fine. But after running for several months with a code that
ran just fine I felt very unconfortable with this bug over a specific
date.

Seebs wrote:

That’s fascinating. I’ve not used strptime much, so I don’t know what
it guesses at by default. It might be interesting to experiment with
nearby times (other times on the same date, for instance) to see whether
you can narrow down the problem.

-s

As far as I’ve seen even 00:00:00 on Oct 31 and times like 10:00:00 also
don’t parse.
At the same time, 23:59:59 on Oct 30 does parse by default.

On 2009-11-01, Jacob G. [email protected] wrote:

I don’t know why this should matter. It’s bug still.

I would tend to agree, I was just suggesting a possible explanation.

I’ve now figured out that an explicit
DateTime.strptime(‘17:26:33 Oct 31, 2009 PST’, ‘%T %b %d, %Y %Z’)
will work fine. But after running for several months with a code that
ran just fine I felt very unconfortable with this bug over a specific
date.

That’s fascinating. I’ve not used strptime much, so I don’t know what
it guesses at by default. It might be interesting to experiment with
nearby times (other times on the same date, for instance) to see whether
you can narrow down the problem.

-s

On Sun, Nov 1, 2009 at 9:20 AM, Jordi B. [email protected] wrote:

On Nov 1, 2009, at 2:33 AM, Jacob G. wrote:

Oct 30 and most other dates parses fine and run fine. Time, year or
timezone don’t matter.

Using 1.8.6-p383, I can’t get valid dates in that format. ‘17:26:33 Oct 31,
2009’ gives me an exception, much like you, but then:

Must be the ghosts. :-/

On Nov 1, 2009, at 2:33 AM, Jacob G. wrote:

Oct 30 and most other dates parses fine and run fine. Time, year or
timezone don’t matter.

Using 1.8.6-p383, I can’t get valid dates in that format. ‘17:26:33
Oct 31, 2009’ gives me an exception, much like you, but then:

~ $ ruby -v
ruby 1.8.6 (2009-08-04 patchlevel 383) [i686-darwin10.0.0]

~ $ ruby -rdate -ryaml -e “puts Date.parse(‘17:26:33 Oct 30,
2009’).to_yaml”
— 2009-11-30

~ $ ruby -rdate -ryaml -e “puts Date.parse(‘17:26:33 Dec 30,
2009’).to_yaml”
— 2009-11-30

~ $ ruby -rdate -ryaml -e “puts Date.parse(‘17:26:33 Feb 30,
2009’).to_yaml”
— 2009-11-30

~ $ ruby -rdate -ryaml -e “puts Date.parse(‘10:01:02 Jan 30,
2009’).to_yaml”
— 2009-11-30

In 1.8.7-p72 I get an exception for all of those, as well as in 1.9.1-
p243

On Sun, Nov 1, 2009 at 10:20 AM, Jordi B. [email protected]
wrote:

— 2009-11-30
Not that the month seems to be being ignored in all of these.


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

Jacob G. wrote:

I don’t know why this should matter. It’s bug still.

I’ve now figured out that an explicit
DateTime.strptime(‘17:26:33 Oct 31, 2009 PST’, ‘%T %b %d, %Y %Z’)
will work fine. But after running for several months with a code that
ran just fine I felt very unconfortable with this bug over a specific
date.

I don’t think it’s a bug – I think it’s being used wrong.

Date.parse expects a date string, not a date time string.
It also expects it to be formatted in a way that it understands.
See the Docs. Use the example given above if you must you this string
format.

irb(main):008:0> puts Date.parse(‘Oct 31, 2009’)
2009-10-31
=> nil
irb(main):009:0> puts Date.parse(‘Oct 31 2009’)
2009-10-31
=> nil
irb(main):010:0> puts Date.parse(‘2009 Oct 31’)
2009-10-31
=> nil

Same with DateTime
irb(main):005:0> puts DateTime.parse(‘17:26:33 Oct 30 2009’)
2009-11-30T20:09:33+00:00
=> nil
irb(main):006:0> puts DateTime.parse(‘17:26:33 2009 Oct 30’)
2009-10-30T17:26:33+00:00
=> nil

On Sun, Nov 1, 2009 at 6:13 PM, Reid T. [email protected]
wrote:

It’s suspiciously close to a range where you would be in a daylight
just fine I felt very unconfortable with this bug over a specific date.
=> nil
2009-11-30T20:09:33+00:00
=> nil
irb(main):006:0> puts DateTime.parse(‘17:26:33 2009 Oct 30’)
2009-10-30T17:26:33+00:00
=> nil

I’m a bit curious why the first DateTime example seems to have
interpreted the date as NOVEMBER 30.

Also, Ruby 1.9’s Date/DateTime parsing is much more picky about what
it understands. For example it used to go to some lengths to use
heuristics to allow either US or international month day ordering, but
no longer.


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

Brian C. wrote:

So you can see that “Oct” is taken as the timezone, and there is no
month. I expect it’s subsequently defaulting the month to the current
month (Nov), and that’s why you’re not allowed the 31st.

Thanks, Brian. Looks like the best explanation.
This also means that the fact that it worked fine for the rest of
October was totally by the lucky coincidence that my code worked in
real-time - i.e. processing data for the current month. So the month was
automatically set to the current (October in this case).

Anyway, I moved to the manual parsing with strftime, which leaves the
code no place to guess.

Thanks all for taking care.

Jacob G. wrote:

Hi,

For some reason ruby 1.8.6 return invalid date exception when parsing a
date of Oct 31 (yesterday) in the format above. Oct 30 and most other
dates parses fine and run fine. Time, year or timezone don’t matter.

I doubt it “parses fine” by your definition:

Date.parse(‘17:26:33 Oct 30, 2009’).to_s
=> “2009-11-30”

If you want to see why, the source to date.rb is there. The heavy
lifting is in Date._parse from date/format.rb, which you can walk
through by hand easily enough.

require ‘date’
=> true

str = ‘17:26:33 Oct 30, 2009’
=> “17:26:33 Oct 30, 2009”

e = Date::Format::Bag.new
=> #<Date::Format::Bag:0xb7b2daec @elem={}>

str.gsub!(/[^-+’,./:[email protected]\x80-\xff]+/in, ’ ')
=> “17:26:33 Oct 30, 2009”

Date.class_eval { _parse_time(str, e) }
=> true

Date.class_eval { _parse_day(str, e) }
=> nil

e.to_hash
=> {:zone=>“Oct”, :sec=>33, :hour=>17, :min=>26}

str
=> " 30, 2009"

Date.class_eval {
?> _parse_eu(str, e) ||
?> _parse_us(str, e) ||
?> _parse_iso(str, e) ||
?> _parse_jis(str, e) ||
?> _parse_vms(str, e) ||
?> _parse_sla_us(str, e) ||
?> _parse_iso2(str, e) ||
?> _parse_year(str, e) ||
?> _parse_mon(str, e) ||
?> _parse_mday(str, e) ||
?> _parse_ddd(str, e)

}
=> true

e.to_hash
=> {:zone=>“Oct”, :sec=>33, :hour=>17, :mday=>30, :min=>26}

So you can see that “Oct” is taken as the timezone, and there is no
month. I expect it’s subsequently defaulting the month to the current
month (Nov), and that’s why you’re not allowed the 31st.

HTH,

Brian.

On Mon, 2009-11-02 at 08:23 +0900, Rick DeNatale wrote:

irb(main):009:0> puts Date.parse(‘Oct 31 2009’)
=> nil
no longer.

Because it doesn’t understand the order of the portions of the input
string

$ irb
irb(main):016:0> puts DateTime.parse(‘Oct 30 2009 17:26:33’)
2009-10-30T17:26:33+00:00
=> nil

versus

irb(main):001:0> puts DateTime.parse(‘17:26:33 Oct 30 2009’)
2009-11-30T20:09:33+00:00
=> nil
irb(main):002:0> puts DateTime.parse(‘17:26:33 Oct 30 2009’)
2009-11-30T20:09:33+00:00
=> nil
irb(main):003:0> puts DateTime.parse(‘17:26:33 Nov 30 2009’)
2009-11-30T20:09:33+00:00
=> nil
irb(main):004:0> puts DateTime.parse(‘17:26:33 Dec 30 2009’)
2009-11-30T20:09:33+00:00
=> nil
irb(main):005:0> puts DateTime.parse(‘17:26:33 Jan 30 2009’)
2009-11-30T20:09:33+00:00
=> nil
irb(main):006:0> puts DateTime.parse(‘17:26:33 Jan 10 2009’)
2009-11-10T20:09:33+00:00
=> nil
irb(main):007:0> puts DateTime.parse(‘Jan 30 2009’)
2009-01-30T00:00:00+00:00
=> nil
irb(main):008:0> puts DateTime.parse(‘17:26 Jan 10 2009’)
2009-11-10T20:09:00+00:00
=> nil
irb(main):009:0> puts DateTime.parse(‘17 Jan 10 2009’)
0010-01-17T00:00:00+00:00
=> nil
irb(main):010:0> puts DateTime.parse(‘10 Jan 10 2009’)
0010-01-10T00:00:00+00:00
=> nil
irb(main):011:0> puts DateTime.parse(‘1 Jan 10 2009’)
0010-01-01T00:00:00+00:00
=> nil
irb(main):012:0> puts DateTime.parse(‘1 12 10 2009’)
2009-11-12T10:00:00+00:00
=> nil
irb(main):013:0> puts DateTime.parse(‘12 10 2009’)
2009-11-12T10:00:00+00:00
=> nil
irb(main):014:0> puts DateTime.parse(‘12 10 2009 0’)
2009-11-12T10:00:00+00:00
=> nil