Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails timestamps don't use the right timezone

I'm a bit confused about timezones in rails. I want my rails app to use British Summer Time (like daylight savings in the US) for the timestamps set in updated_at and created_at in my models. I changed my environment.rb to say

  config.time_zone = 'London'

The ubuntu server my app is on seems to use BST for it's time: in the command line, for example, if i type 'date' i get the current time (not offset by an hour). In the rails console, i see the following:

>> time = Time.now
=> Wed Oct 27 16:29:17 +0100 2010
>> time.zone
=> "BST"

All fine. However, if i make a new AR model object and save it, the timestamps are from an hour ago. So, it looks like this is using UTC. Now, i can see the logic in this: since the timestamps might be used in the model logic, you want them to be based on an unvarying yardstick time, ie UTC. But, this is a weird bit of behaviour that i don't understand:

#change a record and save it
>> someobj.save
=> true
#object's updated_at is one hour ago
>> someobj.updated_at
=> Wed, 27 Oct 2010 15:34:22 UTC +00:00
>> Time.now
=> Wed Oct 27 16:34:31 +0100 2010
#however, Time.now - object's updated at is just a few seconds.
>> Time.now - someobj.updated_at
=> 15.305549

So, before doing the subtraction, updated_at is converted into the current time zone.

The reason i want to show the date in the current time zone is just for status reports etc in the views: if someone updates something i want them to see that it was updated '1 minute ago' not 'one hour ago'.

Can anyone unconfuse me? cheers, max

EDIT: My immediate problem, of showing the right time in the status, is solved by using the 'time_ago_in_words' helper, which adjusts for time zone. I'd still like someone to explain what's going on with the timestamps though :)

like image 674
Max Williams Avatar asked Oct 27 '10 15:10

Max Williams


People also ask

Is timestamp affected by timezone?

No, epoch timestamp should not change, because it has a fixed timezone which is UTC.

Is timestamp stored with timezone?

The timestamp datatype allows you to store both date and time. However, it does not have any time zone data. It means that when you change the timezone of your database server, the timestamp value stored in the database will not change automatically.

Is timestamp stored in UTC?

Internally, the timestamp is as an integer, representing seconds in UTC since the epoch ( 1970-01-01 00:00:00 UTC ) and TIMESTAMPTZ values also stored as integers with respect to Coordinated Universal Time (UTC).


2 Answers

Timestamps are stored in UTC by default, and this is probably the best way to do it. If you move from one server environment to another, you don't want all of your times shifting around just because you switched time zones.

If you want to know what the timestamp is in your local time zone, you just have to ask for it that way:

someobj.updated_at.localtime
like image 58
tadman Avatar answered Oct 16 '22 23:10

tadman


Note the offset listed at the end of the times -- the first offset is 0, the second is 1. When the time calculation occurs, the offset is included automatically, so that the subtraction gives you the correct result. someobj.updated_at and Time.now each displays its value in a different time zone, so they are really only 9 seconds apart, not 1 hour and 9 seconds.

like image 43
zetetic Avatar answered Oct 17 '22 00:10

zetetic