datetime_select preselects wrong times upon edit #9610

Closed
GSI opened this Issue Mar 8, 2013 · 3 comments

Comments

Projects
None yet
2 participants

GSI commented Mar 8, 2013

Note that the following was working correctly in Rails 3.2.6. I skipped the versions between, but can confirm at least that it fails 3.2.11 & 3.2.12.

Given an Event class with:

t.datetime "beginx"
t.datetime "endx"
t.string   "time_zone"

And an edit action like so:

@event = Event.find(id)
Time.zone = @event.time_zone
@event.beginx = @event.beginx.in_time_zone
@event.endx = @event.endx.in_time_zone

In the datetime_select, beginx and endx should shown in regards to the time zone of the event.

Instead, they are shown in the time zone as defined in the before_filter of the application controller (Time.zone = whatever).

If the code of the edit action is changed to the following, suddenly the time is shown within the time zone of the event:

@event = Event.find(id)
Time.zone = @event.time_zone
@event.beginx = @event.beginx.in_time_zone + 1.second
@event.endx = @event.endx.in_time_zone - 1.second

Note the +/- second.
(It's irrelevant which calculation is done - as long as one is done.)

The problem is also described in this SO-question: http://stackoverflow.com/questions/15209130/how-can-i-prefill-datetime-select-with-times-in-custom-time-zone

Owner

pixeltrix commented Mar 8, 2013

This is because the conversion is cached and when you try to assign the new value it sees it as the same value because it's converted to UTC first so it's never cleared. Rather than changing the global Time.zone setting you'd be better off overriding the readers for those attributes, e.g:

class Event < ActiveRecord::Base
  def beginx
    super.in_time_zone(time_zone)
  end

  def endx
    super.in_time_zone(time_zone)
  end
end

This will ensure that the values are always in the correct time zone.

GSI commented Mar 9, 2013

Excellent hint. Thanks. To avoid errors I added if super:

super.in_time_zone(time_zone) if super
Owner

pixeltrix commented Mar 9, 2013

@GSI yes, if you can have nil values in the column then you need to detect that. Other ways of doing it are:

super && super.in_time_zone(time_zone)

or

super.try(:in_time_zone, time_zone)

Which you prefer is down to you - I know some people have an ideological objection to the last one 😄

Closing the ticket because it's working as it should be - thanks for your report though.

@pixeltrix pixeltrix closed this Mar 9, 2013

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