chronic icon indicating copy to clipboard operation
chronic copied to clipboard

Daylight Savings not handled properly

Open bricker opened this issue 12 years ago • 10 comments

Daylight savings "falls back" in the states on November 4th, 2012, at exactly 2am. It goes backwards and repeats the 1am hour.

Time.new(2012, 11, 4, 0)
# => 2012-11-04 00:00:00 -0700

Chronic.parse("2012-11-04 at 12am")
# => 2012-11-04 01:00:00 -0700

Chronic.parse("2012-11-04")
# => 2012-11-04 11:00:00 -0800 

Those first two dates should return the same, and I would expect the last one to return 12pm. Hopefully this is a silly mistake I'm making, or there is a reasonable explanation. DST is a nightmare!

bricker avatar Oct 28 '12 23:10 bricker

Probably related, this morning, my Chronic calls started straight up failing right at 2AM when DST kicked over.

Chronic.parse('tomorrow at 4:00 pm')

Is now nil. Argh?

1.9.2p320 :006 > Chronic.parse('tomorrow at 4:00 pm')
 => nil 
1.9.2p320 :007 > 

I'm currently setting the timezone like so, if that matters:

Time.zone = "Pacific Time (US & Canada)"
Chronic.time_class = Time.zone

Setting the timezone to 'UTC' seems to fix it. But I am wondering why this worked all the way until yesterday but not today?

travisbell avatar Nov 04 '12 20:11 travisbell

I ran into the exact same issue today described by @travisbell above.

markerdmann avatar Nov 05 '12 00:11 markerdmann

I also encountered the same error as @bricker - has there been any updates on this?

wakiki avatar Mar 12 '13 09:03 wakiki

No there hasn't, I'm struggling to find time for Chronic at the moment. Hoping to start hitting some of these as soon as possible

leejarvis avatar Mar 12 '13 11:03 leejarvis

@injekt I have some time to work on this. I'll fork and send a pull request if I have any luck. Do you have an idea of where in the codebase I might start looking to find the source of the bug?

markerdmann avatar Mar 12 '13 18:03 markerdmann

I don't know if this is the same issue but I noted the following in issue #179

1.9.3p362 :021 > Time.current => Tue, 12 Mar 2013 11:01:30 GMT +00:00 1.9.3p362 :017 > Time.zone = "London" => "London" 1.9.3p362 :018 > Chronic.time_class = Time.zone => (GMT+00:00) London 1.9.3p362 :019 > Chronic.parse("April 1st at 9am") => Mon, 01 Apr 2013 09:00:00 BST +01:00 1.9.3p362 :020 > Chronic.parse("20 days from now at 9am") => Mon, 01 Apr 2013 10:00:00 BST +01:00

Interestingly, specifying "April 1st" works fine whereas "20 days from now" doesn't work.

Chronic 0.9.1 Rails 3.2.6

wakiki avatar Mar 12 '13 18:03 wakiki

@markerdmann sorry I hadn't noticed your message until today. I can't reproduce the original issue so it'll probably take me a little longer to fix. Usually I would enable debug mode (Chronic.debug = true) then jump into the method that handles this sequence (in Handlers) then debug things from there. It's not always a quick process and there's a few subtle bugs in Chronic that aren't easy to fix. I do still have a rewrite that's currently in progress but again I'm finding it hard to find work on this at the moment, everything is tied up with work

leejarvis avatar Mar 23 '13 13:03 leejarvis

We ran into this in https://github.com/floraison/et-orbi/issues/23 as well. I think these lines are questionable: https://github.com/mojombo/chronic/blob/2b1eae7ec440d767c09e0b1a7f0e9bcf30ce1d6c/lib/chronic/repeaters/repeater_time.rb#L81-L96

Try passing in Chronic.parse('2020-11-01 00:00:00') on a system that has daylight savings:

Time.parse('2020-11-01 00:00:00')
=> 2020-11-01 00:00:00 -0700
Chronic.parse('2020-11-01 00:00:00')
=> 2020-11-01 01:00:00 -0700

Why did Chronic advance an hour like that?

When a date like this is passed in Chronic.parse, offset_fix becomes 3600 (1 hour), and the starting time advances by an hour.

If I try to get rid of this offset_fix:

diff --git a/lib/chronic/repeaters/repeater_time.rb b/lib/chronic/repeaters/repeater_time.rb
index 0a496e7..208553e 100644
--- a/lib/chronic/repeaters/repeater_time.rb
+++ b/lib/chronic/repeaters/repeater_time.rb
@@ -87,21 +87,21 @@ module Chronic
         catch :done do
           if pointer == :future
             if @type.ambiguous?
-              [midnight + @type.time + offset_fix, midnight + half_day + @type.time + offset_fix, tomorrow_midnight + @type.time].each do |t|
+              [midnight + @type.time, midnight + half_day + @type.time + offset_fix, tomorrow_midnight + @type.time].each do |t|
                 (@current_time = t; throw :done) if t >= @now
               end
             else
-              [midnight + @type.time + offset_fix, tomorrow_midnight + @type.time].each do |t|
+              [midnight + @type.time, tomorrow_midnight + @type.time].each do |t|
                 (@current_time = t; throw :done) if t >= @now
               end
             end
           else # pointer == :past
             if @type.ambiguous?
-              [midnight + half_day + @type.time + offset_fix, midnight + @type.time + offset_fix, yesterday_midnight + @type.time + half_day].each do |t|
+              [midnight + half_day + @type.time, midnight + @type.time + offset_fix, yesterday_midnight + @type.time + half_day].each do |t|
                 (@current_time = t; throw :done) if t <= @now
               end
             else
-              [midnight + @type.time + offset_fix, yesterday_midnight + @type.time].each do |t|
+              [midnight + @type.time, yesterday_midnight + @type.time].each do |t|
                 (@current_time = t; throw :done) if t <= @now
               end
             end

Tests like the following fail: https://github.com/mojombo/chronic/blob/2b1eae7ec440d767c09e0b1a7f0e9bcf30ce1d6c/test/test_daylight_savings.rb#L38-L41.

stanhu avatar Nov 22 '19 18:11 stanhu

I think https://github.com/mojombo/chronic/pull/396 fixes this problem.

stanhu avatar Nov 23 '19 15:11 stanhu

Facing the same issue. Parsing is advance me to the next day. See the screenshot Selection_009

aviisekh avatar Mar 20 '20 09:03 aviisekh