views:

59

answers:

2

I'm working on a Rails application that's kind of like a blog. Users create Entries. I'm trying to work out how to handle time storage and display. I've read this writeup about Rails timezone support.

It's great but it doesn't cover what my app needs to do. It only looks at cases where you want to convert stored time to the current logged in user's time zone. In contrast, the effect I want is...

  • A user creates an entry in California at 10:00 a.m.

  • A couple years later he moves to New York and then at some point looks at his old entry. The "created" date should say "10:00 a.m." He doesn't care about time zones. He just wants to know what time of day he felt like it was when he wrote the entry.

  • If he then edits the Entry in New York the displayed "modified" date is, again, his subjective time of day when he made the edit. (Let's assume he went to "preferences" and changed his time zone setting when he moved.)

  • Also, for the sake of thoroughness, the app should be able to report the "real" absolute time when an Entry was created or updated.

(Note -- my imaginary user is a guy, but for women it should work roughly the same way.)

The way I'm thinking of implementing it is...

  • Have the attributes User#time_zone, Entry#created_at_utc, and Entry#updated_at_utc in addition to the standard created_at and updated_at.

  • The user selects their time zone from a menu when they sign up. (They can change it later if they want.)

  • The app uses User#time_zone to store created_at and updated_at in the user's subjective local time. If it's 10:00 a.m. for them, the app writes "10:00 a.m." to the DB.

  • The app also saves the current UTC time in the aforementioned _utc fields to deal with the last requirement above.

Is that a good way to do it? Is there a better way?

+1  A: 

If you can, you should avoid storing two different sets of timestamps, and you should avoid storing any non-UTC dates. Both of these things will lead to confusion. I'm not completely sure I understand what you're doing (though I like your idea of subjective time), but wouldn't it be enough to just attach a time zone to every post, and always use that zone to display the times? It would default to the time zone set in the author's account, so he could change it when he moved cross-country without affecting previous posts.

I think that's all you need--to attach a time zone to every post. Is that sufficient? Or am I missing some part of this?

Alex Reisner
Great, you're right. Except I think I need both `created_time_zone` and `updated_time_zone` because the user could create an entry in CA then move to NY and update. To display each timestamp accurately, the app needs to know the time zone where the user was when it was written.
Ethan
+2  A: 

The two roads you can take are:

  1. Store a timezone (UTC) in the user account as well as in every post - update the post's timezone along with the updated_at field whenever the user changes the post (if he or she has changed timezones).
  2. Store the timezone only in the user account. When the user changes timezones, update every post that belongs to the user and add/subtract to the created_at/updated_at dates.

The first option seems like the cleanest option to take. For this you would only have to create a new method in your post record:

def locational_updated_at
  updated_at + timezone.seconds
end

Where timezone is an integer containing the seconds since UTC.

Benjamin Manns