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

Solution 1:

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.

Solution 2:

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

Solution 3:

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

Solution 4:

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.