Skip to content

Instantly share code, notes, and snippets.

@mando
Created October 2, 2012 03:27
Show Gist options
  • Save mando/3815988 to your computer and use it in GitHub Desktop.
Save mando/3815988 to your computer and use it in GitHub Desktop.
Time Zones say WHA?
$ rails -v
Rails 3.2.8
$ rails c
Loading development environment (Rails 3.2.8)
1.9.3-p194 :001 > Time.zone = 'Paris'
=> "Paris"
1.9.3-p194 :002 > t = Time.zone
=> (GMT+01:00) Paris # HUH? Paris is GMT+02:00 right now, thanks to DST
Now deep in the bowels of ActiveSupport::TimeZone, we have the following:
def utc_offset
if @utc_offset
@utc_offset
else
@current_period ||= tzinfo.try(:current_period)
@current_period.try(:utc_offset)
end
end
Now, TZInfo has a fancy method called utc_total_offset that, according to the docs, does the following:
utc_total_offset() - Total offset from UTC (seconds). Equal to utc_offset + std_offset.
A HA! std_offset? As in, an offset that's added to the utc_offset when a time zone is in DST?
When we patch this ActiveSupport method to use utc_total_offset instead of the dumber utc_offset, we get the following:
$ rails c
Loading development environment (Rails 3.2.8)
1.9.3-p194 :001 > Time.zone = 'Paris'
=> "Paris"
1.9.3-p194 :002 > t = Time.zone
=> (GMT+02:00) Paris # HUZZAH!!!!
@ascruggs
Copy link

ascruggs commented Oct 2, 2012

Try typing:

[11] pry(main)> Time.zone.now
=> Tue, 02 Oct 2012 05:43:25 CEST +02:00

Note that it gives you the 2 hour offset.

I think that is stores the zone w/o DST context so that it can be persisted. Then calculates the correct offset at the time of evaluation to ensure it is accurate when needed.

Imagine an application that was up and running at the time that DST took affect. It would need to calculate the offset at the time of evaluation, not the time that it was set/stored.

@ascruggs
Copy link

ascruggs commented Oct 2, 2012

Disclaimer: this is more conjecture than tracing code/digging into AS, but I think the evaluation of the current time strongly supports this theory.

@mando
Copy link
Author

mando commented Oct 2, 2012

You're exactly right :).

The calculations are correct - it's purely a display issue. But it's a pretty lousy one - in our time zone picker, the value you select is Paris (GMT+01:00) but Rails saves any datetime in that timezone as GMT+2 :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment