This project is archived and is in readonly mode.
Time.current.utc_offset and Time.zone.utc_offset are different during DST
Reported by ronin-41535 (at lighthouseapp) | August 12th, 2009 @ 12:14 AM
Asking a TimeZone for its utc_offset, and a TimeWithZone object in the same TimeZone for its utc_offset return different results. For example:
>> Time.zone = "Eastern Time (US & Canada)"
=> "Eastern Time (US & Canada)"
>> Time.zone.utc_offset
=> -18000
>> Time.current.utc_offset
=> -14400
The offending code is in
ActiveSupport::TimeZone#utc_offset
:
def utc_offset
@utc_offset ||= tzinfo.current_period.utc_offset
end
In contrast, ActiveSupport::TimeWithZone#utc_offset
calls utc_total_offset
on the underlying period:
def utc_offset
period.utc_total_offset
end
I believe the implementation in
ActiveSupport::TimeWithZone#utc_offset
is correct, and
propose that TimeZone
's implementation also call
utc_total_offset
. This way, the two offsets match each
other, and match the offset displayed when calling
Time.current
.
Comments and changes to this ticket
-
CancelProfileIsBroken September 25th, 2009 @ 12:54 PM
- Tag set to bugmash
-
John Trupiano September 26th, 2009 @ 04:23 PM
Verified that it's only a problem in DST.
john-mbp:rails john$ ruby script/console Loading development environment (Rails 3.0.pre) /Users/john/projects/rails/rails/config/environment.rb:11: warning: already initialized constant Application >> Time.zone = "Eastern Time (US & Canada)" => "Eastern Time (US & Canada)" >> Time.now => Sat Sep 26 11:19:42 -0400 2009 >> Time.zone.utc_offset => -18000 >> Time.current.utc_offset => -14400 >> require 'timecop' => [] >> Timecop.travel(2009, 12, 12) => Sat Dec 12 00:00:00 -0500 2009 >> Time.zone.utc_offset => -18000 >> Time.current.utc_offset => -18000
Using Timecop to move ahead to Dec, these two methods do in fact return the same value. It would appear that Vladimir's assertion that they should both return 14400 during DST is correct.
-
John Trupiano September 26th, 2009 @ 04:30 PM
Now that I think about this further, I'm not sure that a change is warranted. A TimeZone object exists outside of the context of an actual Time instance. It's somewhat arbitrary to return its utc_offset based on Time.now. In essence, I don't think a TimeZone should consult "now" when asked for its offset. A TimeWithZone object carries with it a specific Time instance, and so it makes sense for it to take DST into account.
-1 on changing this.
-
David Trasbo September 26th, 2009 @ 06:31 PM
+1 verified
Given I don't misunderstand I'll have to disagree with John. I took a look at the docs for Time.current() ...
Returns Time.zone.now when config.time_zone is set, otherwise just returns Time.now.
and Time.zone() ...
Returns the TimeZone for the current request, if this has been set (via Time.zone=).
... and concluded that since Time.current() depends on Time.zone() they should have the same utc_offset. Please do correct me if I'm wrong, though.
-
John Trupiano September 26th, 2009 @ 06:40 PM
My point is that a TimeZone object exists in the absence of a specific time. It's a matter of responsibility. A TimeZone should only take DST into account if it's asked for its utc_offset in the context of a specific Time. Since this is not the case when calling Time.zone, it shouldn't just arbitrarily choose to consult Time.now to determine whether or not to include DST in its calculation.
At no point does a call to Time.zone.utc_offset indicate the exact Time against which you want the utc_offset to be evaluated. If we instead had a function like Time.zone.utc_offset_for_time(a_time), then I'd say yes, we should be including DST in the offset.
Anyone else feel strongly about this?
-
Geoff Buesing October 27th, 2009 @ 02:27 AM
- State changed from new to invalid
TimeZone#utc_offset (called when you call Time.zone.utc_offset) returns just the base UTC offset for the time zone; it doesn't take DST into consideration.
This offset for user friendly display in time_zone_select. For example, the display of "Central Time (US & Canada) is "(GMT-06:00) Central Time (US & Canada)". This offset should not change over the course of the year -- it should always be GMT-06:00.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>