Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a record foo in the database which has :start_time and :timezone attributes.

The :start_time is a Time in UTC - 2001-01-01 14:20:00, for example. The :timezone is a string - America/New_York, for example.

I want to create a new Time object with the value of :start_time but whose timezone is specified by :timezone. I do not want to load the :start_time and then convert to :timezone, because Rails will be clever and update the time from UTC to be consistent with that timezone.

Currently,

t = foo.start_time
=> 2000-01-01 14:20:00 UTC
t.zone
=> "UTC"
t.in_time_zone("America/New_York")
=> Sat, 01 Jan 2000 09:20:00 EST -05:00

Instead, I want to see

=> Sat, 01 Jan 2000 14:20:00 EST -05:00

ie. I want to do:

t
=> 2000-01-01 14:20:00 UTC
t.zone = "America/New_York"
=> "America/New_York"
t
=> 2000-01-01 14:20:00 EST
like image 831
rwb Avatar asked Oct 08 '22 21:10

rwb


People also ask

How do you change timezone in Ruby?

You can do: Time. now + Time. zone_offset("PST") if you: require 'time' in your ruby script. guess, should have done that before commenting.

What is Ruby time?

Advertisements. The Time class represents dates and times in Ruby. It is a thin layer over the system date and time functionality provided by the operating system. This class may be unable on your system to represent dates before 1970 or after 2038.


2 Answers

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.

like image 84
Frederick Cheung Avatar answered Oct 23 '22 12:10

Frederick Cheung


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

like image 50
Zhenya Avatar answered Oct 23 '22 11:10

Zhenya