Handling User-Entered Dates with Time Zones

In this app, a user enters a date. To be friendly, the user can enter
dates in any time zone. (The source data may be in any number of time
zones, so this isn’t a sticky preference, it could vary on each date
they submit.) This date and time in the arbitrary time zone though,
should then be converted to UTC and stored in the database. Sounds easy.

Let’s say I have an example simple view:

<% form_for(@event) do |f| %>
<%= time_zone_select nil, :time_zone, ActiveSupport::TimeZone.us_zones
%>
<%= f.datetime_select :start %>
… many other model fields …
<% end %>

In the response, it’d roughly be this simple:

def method
@event = Event.find(params[:id])

if @event.update_attributes(params[:event])
yay
end
end

…except that doing this, Rails interprets the datetime the user
entered in my configured default time zone (UTC). Instead, I need to use
the time zone the user specified. So after failing to find any good way
to do this, it seems to me, the shortest way to do this is:

def method
@event = Event.find(params[:id])

zone = ActiveSupport::TimeZone.new(params[:time_zone])
yr = params[:event][:“start(1i)”].to_i
mon = params[:event][:“start(2i)”].to_i
day = params[:event][:“start(3i)”].to_i
hr = params[:event][:“start(4i)”].to_i
min = params[:event][:“start(5i)”].to_i
sec = 0
off = zone.utc_offset / 86400.0

@event.attributes = params[:event]
@event.start = DateTime.civil(yr, mon, day, hr, min, sec, off)

if @event.save
yay
end
end

I can obviously make a separate method to factor out creating a date
with the given time zone, but there has to be a better way overall of
doing this.

Any suggestions?

On 25 Mar 2011, at 04:27, Seth W. <lists@ruby-forum.

…except that doing this, Rails interprets the datetime the user
entered in my configured default time zone (UTC). Instead, I need to use
the time zone the user specified. So after failing to find any good way
to do this, it seems to me, the shortest way to do this is:

How about setting Time.zone to whatever the user supplies before
updating your event object?

Fred