0

I have been using Chronic successfully in my Rails app for a few weeks. I haven't been doing anything fancy with it, just using it to parse basic time inputs like '1:21pm' or '1440' etc. Everything was working fine up until today when I ran my test suite and came across a very odd failure.

These all work:

Chronic.parse('1:21am')
=> 2016-10-02 00:21:00 +1000
Chronic.parse('0121')
=> 2016-10-03 01:21:00 +1100
Chronic.parse('0021')
=> 2016-10-03 00:21:00 +1100
Chronic.parse('1:21 AM')
=> 2016-10-02 00:21:00 +1000

However 12:21 AM returns nil:

Chronic.parse('12:21 AM')
=> nil

In my code I'm actually doing a strftime to strip out the date and just keep the time because that's all I care about. But naturally that doesn't work when Chronic returns nil.

self.time = Chronic.parse(time).try(:strftime, '%l:%M %p')

What's interesting is that this morning daylight savings kicked in for my timezone, Sydney. I haven't changed anything else around this code for a while, so my guess is that it's related.

Benjamin Humphrey
  • 3,770
  • 2
  • 23
  • 41
  • Did you see this? https://github.com/mojombo/chronic/issues/328 – Alexandre Angelim Oct 02 '16 at 02:14
  • @AlexandreAngelim Ah cool, no I didn't see that. I tried the suggested guess: :begin solution but that didn't work. What do you recommend? Looks like it might be solved in that rewrite PR that's mentioned. I could target that. – Benjamin Humphrey Oct 02 '16 at 02:28
  • You're gonna hate me for this, but I think you could test if the result of Chronic is `nil` and use `tomorrow #{time}`. It will get to a day when that time actually exists and you don't need the day anyway. So something like this `(Chronic.parse(time) || Chronic.parse("tomorrow #{time}")).try(:strftime, '%l:%M %p')` – Alexandre Angelim Oct 02 '16 at 02:52
  • Another option is just to tell Chronic to use a specific day that we know is not daylight savings. Since I only use the time, and not the date, that should work okay. However I can't figure out how to pass through a specific date to Chronic. – Benjamin Humphrey Oct 02 '16 at 10:16
  • They say it accepts specific dates like `5/27/1979`. I assume `5/27/1979 at 12:21 AM` works. – Alexandre Angelim Oct 02 '16 at 12:58

1 Answers1

0

There are two solutions:

A) Tell Chronic to use Time.zone

This way worked for me. Basically:

Chronic.time_class = Time.zone
self.time = Chronic.parse(time).try(:strftime, '%l:%M %p')

B) Parse using a fixed date that is not affected by daylight savings

Since I am only interested in the time and not the date, in this case we could use a specific date that we know is not affected by daylight savings when parsing the time. For example:

Chronic.parse("5/27/1979 at #{time}").try(:strftime, '%l:%M %p')
Benjamin Humphrey
  • 3,770
  • 2
  • 23
  • 41