Ruby / Rails - Change the timezone of a Time, without changing the value

I've just faced the same problem and here is what I'm going to do:

t = t.asctime.in_time_zone("America/New_York")

Here is the documentation on asctime


Sounds like you want something along the lines of

ActiveSupport::TimeZone.new('America/New_York').local_to_utc(t)

This says convert this local time (using the zone) to utc. If you have Time.zone set then you can of course to

Time.zone.local_to_utc(t)

This won't use the timezone attached to t - it assumes that it's local to the time zone you are converting from.

One edge case to guard against here is DST transitions: the local time you specify may not exist or may be ambiguous.


You need to add the time offset to your time after you convert it.

The easiest way to do this is:

t = Foo.start_time.in_time_zone("America/New_York")
t -= t.utc_offset

I am not sure why you would want to do this, though it is probably best to actually work with times the way they are built. I guess some background on why you need to shift time and timezones would be helpful.


If you're using Rails, here is another method along the lines of Eric Walsh's answer:

def set_in_timezone(time, zone)
  Time.use_zone(zone) { time.to_datetime.change(offset: Time.zone.now.strftime("%z")) }
end