I have a variable foo that contains a time, lets say 4pm today, but the zone offset is wrong, i.e. it is in the wrong time zone. How do I change the time zone?
When
in you environment.rb search for the following line.
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names.
config.time_zone = 'UTC'
Keep in mind ActiveRecord and Rails always handle Time as UTC internally.
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
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.
Here is what worked for me...
def convert_zones(to_zone)
to_zone_time = to_zone.localtime
end
# have your time set as time
time = convert_zones(time)
time.strftime("%b #{day}, %Y (%a) #{hour}:%M %p %Z")
Option 1
Use date_time_attribute gem:
my_date_time = DateTimeAttribute::Container.new(Time.zone.now)
my_date_time.date_time # => 2001-02-03 22:00:00 KRAT +0700
my_date_time.time_zone = 'Moscow'
my_date_time.date_time # => 2001-02-03 22:00:00 MSK +0400
Option 2
If time is used as an attribute, you can use the same date_time_attribute gem:
class Task
include DateTimeAttribute
date_time_attribute :due_at
end
task = Task.new
task.due_at_time_zone = 'Moscow'
task.due_at # => Mon, 03 Feb 2013 22:00:00 MSK +04:00
task.due_at_time_zone = 'London'
task.due_at # => Mon, 03 Feb 2013 22:00:00 GMT +00:00
This is what I did, as I am not using Rails and don't want to use any non-core gems.
t = Time.now # my local time - which is GMT
zone_offset = 3600 # offset for CET - which is my target time zone
zone_offset += 3600 if t.dst? # an extra hour offset in summer
time_cet = Time.mktime(t.sec, t.min, t.hour, t.mday, t.mon, t.year, nil, nil, t.dst?, zone_offset)
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