chronic
chronic copied to clipboard
Daylight Savings not handled properly
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!
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?
I ran into the exact same issue today described by @travisbell above.
I also encountered the same error as @bricker - has there been any updates on this?
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
@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?
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
@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
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.
I think https://github.com/mojombo/chronic/pull/396 fixes this problem.
Facing the same issue. Parsing is advance me to the next day. See the screenshot