How do I change the zone offset for a time in Ruby on Rails?

You don't explicitly say how you get the actual variable but since you mention the Time class so I'll assume you got the time using that and I'll refer to that in my answer

The timezone is actually part of the Time class (in your case the timezone is shown as UTC). Time.now will return the offset from UTC as part of the Time.now response.

>> local = Time.now
=> 2012-08-13 08:36:50 +0000
>> local.hour
=> 8
>> local.min
=> 36
>> 


... in this case I happen to be in the same timezone as GMT

Converting between timezones

The easiest way that I've found is to change the offset using '+/-HH:MM' format to the getlocal method. Let's pretend I want to convert between the time in Dublin and the time in New York

?> dublin = Time.now
=> 2012-08-13 08:36:50 +0000
>> new_york = dublin + Time.zone_offset('EST')
=> 2012-08-13 08:36:50 +0000
>> dublin.hour
=> 8
>> new_york.hour
=> 3

Assuming that 'EST' is the name of the Timezone for New York, as Dan points out sometimes 'EDT' is the correct TZ.


If given:

2011-10-25 07:21:35 -700

you want:

2011-10-25 07:21:35 UTC

then do:

Time.parse(Time.now.strftime('%Y-%m-%d %H:%M:%S UTC')).to_s

This takes advantage of the fact that Time#asctime doesn't include the zone.

Given a time:

>> time = Time.now
=> 2013-03-13 13:01:48 -0500

Force it to another zone (this returns an ActiveSupport::TimeWithZone):

>> ActiveSupport::TimeZone['US/Pacific'].parse(time.asctime)
=> Wed, 13 Mar 2013 13:01:48 PDT -07:00

Note that the original zone is ignored completely. If I convert the original time to utc, the result will be different:

>> ActiveSupport::TimeZone['US/Pacific'].parse(time.getutc.asctime)
=> Wed, 13 Mar 2013 18:01:48 PDT -07:00

You can use to_time or to_datetime on the result to get a corresponding Time or DateTime.

This question uses an interesting approach with DateTime#change to set the tz offset. (Remember that ActiveSupport makes it easy to convert between Time and DateTime.) The downside is that there's no DST detection; you have to do that manually by using TZInfo's current_period.