Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ambiguous time when parsing dates with daylight savings using Chronic #23

Closed
stanhu opened this issue Nov 22, 2019 · 12 comments
Closed
Assignees

Comments

@stanhu
Copy link
Contributor

stanhu commented Nov 22, 2019

Here's a test that reproduces the problem:

diff --git a/spec/module_spec.rb b/spec/module_spec.rb
index a0c980e..893212f 100644
--- a/spec/module_spec.rb
+++ b/spec/module_spec.rb
@@ -288,6 +288,15 @@ describe EtOrbi do
         expect(t.strftime('%Y-%m-%d')).to eq(t1.strftime('%Y-%m-%d'))
         expect(t.strftime('%H:%M:%S')).to eq('12:00:00')
       end
+
+      it 'handles days that have ambiguous daylight savings conversions' do
+
+        Time.active_support_zone = 'America/Chicago'
+
+        t = EtOrbi.parse('2020-11-01 00:00:00')
+
+        expect(t.class).to eq(EtOrbi::EoTime)
+      end
     end
   end

It fails with:

Failures:

  1) EtOrbi.parse when Chronic is defined handles ambiguous daylight savings conversions
     Failure/Error: secs = zone.local_to_utc(local).to_f

     TZInfo::AmbiguousTime:
       Time: 2020-11-01 01:00:00 UTC is an ambiguous local time.
     # ./lib/et-orbi/make.rb:42:in `parse'
     # ./spec/module_spec.rb:296:in `block (4 levels) in <top (required)>'

I described the problem in-depth in https://gitlab.com/gitlab-org/gitlab/issues/37014#note_248974118.

Essentially, when Chronic is used, the time is advanced unnecessarily:

t = Chronic.parse('2020-11-01 00:00:00')
=> 2020-11-01 01:00:00 -0500
str = [ t.strftime('%F %T'), nil ].compact.join(' ')     
=> "2020-11-01 01:00:00"
zone = TZInfo::Timezone.new("America/Chicago")
=> #<TZInfo::DataTimezone: America/Chicago>
zone.local_to_utc(t)
Traceback (most recent call last):
        9: from /opt/gitlab/embedded/bin/irb:23:in `<main>'
        8: from /opt/gitlab/embedded/bin/irb:23:in `load'
        7: from /opt/gitlab/embedded/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
        6: from (irb):35
        5: from (irb):35:in `rescue in irb_binding'
        4: from /opt/gitlab/embedded/lib/ruby/gems/2.6.0/gems/tzinfo-1.2.5/lib/tzinfo/timezone.rb:464:in `local_to_utc'
        3: from /opt/gitlab/embedded/lib/ruby/gems/2.6.0/gems/tzinfo-1.2.5/lib/tzinfo/time_or_datetime.rb:324:in `wrap'
        2: from /opt/gitlab/embedded/lib/ruby/gems/2.6.0/gems/tzinfo-1.2.5/lib/tzinfo/timezone.rb:468:in `block in local_to_utc'
        1: from /opt/gitlab/embedded/lib/ruby/gems/2.6.0/gems/tzinfo-1.2.5/lib/tzinfo/timezone.rb:409:in `period_for_local'
TZInfo::AmbiguousTime (Time: 2020-11-01 01:00:00 UTC is an ambiguous local time.)

I propose two ways to solve this here:

  1. An option to disable the use of Chronic
  2. Fix the time zone handling when Chronic is in use

Chronic is probably causing issues because it doesn't handle Daylight Savings well: mojombo/chronic#147

stanhu added a commit to stanhu/et-orbi that referenced this issue Nov 22, 2019
@jmettraux jmettraux self-assigned this Nov 22, 2019
@jmettraux
Copy link
Member

@stanhu thanks for the patch, as you've seen, it's merged. I will dig a bit deeper tomorrow morning (HK time).

I will try to reproduce your root issue, since

  Time.active_support_zone = 'America/Chicago'          
  t = EtOrbi.parse('2020-11-01 00:00:00')  

is not making any problem on my system. I'll think about how to trigger that here.

I also have to look at the CI appveyor :-(

When I have something decent, I will release.

Thanks so far.

@stanhu
Copy link
Contributor Author

stanhu commented Nov 22, 2019

@jmettraux Thanks! Did you remember to require 'chronic' first? Have you tried changing the spec that was merged to enable_chronic: false? That fails for me.

@stanhu
Copy link
Contributor Author

stanhu commented Nov 22, 2019

Hmm, we might want to revert #24 since the extra opts are leaking into Chronic options. Besides, I think the real issue is mojombo/chronic#147 (comment).

@jmettraux
Copy link
Member

Did you remember to require 'chronic' first?

Yes,

et-orbi/spec/module_spec.rb

Lines 241 to 243 in 8425ca5

before :each do
require_chronic
end

@stanhu
Copy link
Contributor Author

stanhu commented Nov 23, 2019

It's possible the time zone on your system also matters.

@stanhu
Copy link
Contributor Author

stanhu commented Nov 23, 2019

I've submitted mojombo/chronic#396 to fix this problem.

@jmettraux
Copy link
Member

@stanhu wrote:

It's possible the time zone on your system also matters.

May I know what Ruby version, what OS, and what timezone combination exhibits the problem for you?

Thanks in advance.

@jmettraux
Copy link
Member

@stanhu wrote:

Have you tried changing the spec that was merged to enable_chronic: false? That fails for me.

Yes, I first worked with your spec, but it didn't fail for me, Chronic or no-Chronic. Sorry, I had to change it to reflect the true purpose of enable_chronic: false, turning off Chronic as a middle-man.

@stanhu
Copy link
Contributor Author

stanhu commented Nov 25, 2019

On Linux, it looks like setting the system clock via timedatectl makes the EtOrbi.parse('2020-11-01 00:00:00', enable_chronic: true) test fail:

timedatectl set-timezone "America/Chicago"

@jmettraux
Copy link
Member

@stanhu What Linux flavour, what Ruby version, what Chronic version? Thanks in advance.

@stanhu
Copy link
Contributor Author

stanhu commented Nov 25, 2019

@jmettraux I've been using Ubuntu 18.04, Ruby 2.6.3, and Chronic v0.10.2.

@jmettraux
Copy link
Member

Thanks for all the investigation work and the contributions. Since it's Chronic issue, I am closing this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants