I'm having trouble converting a UTC Time
or TimeWithZone
to local time in Rails 3.
Say moment
is some Time
variable in UTC (e.g. moment = Time.now.utc
). How do I convert moment
to my time zone, taking care of DST (i.e. using EST/EDT)?
More precisely, I'd like to printout "Monday March 14, 9 AM" if the time correspond to this morning 9 AM EDT and "Monday March 7, 9 AM" if the time was 9 AM EST last monday.
Hopefully there's another way?
Edit: I first thought that "EDT" should be a recognized timezone, but "EDT" is not an actual timezone, more like the state of a timezone. For instance it would not make any sense to ask for Time.utc(2011,1,1).in_time_zone("EDT")
. It is a bit confusing, as "EST" is an actual timezone, used in a few places that do not use Daylight savings time and are (UTC-5) yearlong.
Time#localtime
will give you the time in the current time zone of the machine running the code:
> moment = Time.now.utc
=> 2011-03-14 15:15:58 UTC
> moment.localtime
=> 2011-03-14 08:15:58 -0700
Update: If you want to conver to specific time zones rather than your own timezone, you're on the right track. However, instead of worrying about EST vs EDT, just pass in the general Eastern Time zone -- it will know based on the day whether it is EDT or EST:
> Time.now.utc.in_time_zone("Eastern Time (US & Canada)")
=> Mon, 14 Mar 2011 11:21:05 EDT -04:00
> (Time.now.utc + 10.months).in_time_zone("Eastern Time (US & Canada)")
=> Sat, 14 Jan 2012 10:21:18 EST -05:00
Rails has its own names. See them with:
rake time:zones:us
You can also run rake time:zones:all
for all time zones. To see more zone-related rake tasks: rake -D time
So, to convert to EST, catering for DST automatically:
Time.now.in_time_zone("Eastern Time (US & Canada)")
(new Date()).getTimeZoneOffset()
. But it's fairly inconsistent, so this guy seems to have written his own: onlineaspect.com/2007/06/08/…
config.time_zone = 'Wellington'
and then use Time.current (which is equivalent to time.now but used the Timezone that you have set)
It is easy to configure it using your system local zone, Just in your application.rb add this
config.time_zone = Time.now.zone
Then, rails should show you timestamps in your localtime or you can use something like this instruction to get the localtime
Post.created_at.localtime
There is actually a nice Gem called local_time
by basecamp to do all of that on client side only, I believe:
https://github.com/basecamp/local_time
Don't know why but in my case it doesn't work the way suggested earlier. But it works like this:
Time.now.change(offset: "-3000")
Of course you need to change offset
value to yours.
If you're actually doing it just because you want to get the user's timezone then all you have to do is change your timezone in you config/applications.rb
.
Like this:
Rails, by default, will save your time record in UTC even if you specify the current timezone.
config.time_zone = "Singapore"
So this is all you have to do and you're good to go.
Success story sharing
in_time_zone
method with their timezone.Time.now.localtime
works on a normal irb session but when I try to run it on a machine which is in UTC timezone, it doesnt work.