1

I'm currently storing all times in UTC, to make things easier for when I start bringing multiple sites and servers online.

The problem comes in when translating date and datetime objects into strings in my templates and when accepting user input. 6:00PM UTC doesn't mean a whole lot to someone who is in PST. Likewise, asking users to input times in UTC is asking for disaster.

How can I correctly translate these values in a smart, not-error-prone way? Is there a way I can determine from the HTTP request what timezone a user is in? I really need a way to determine the user's timezone with as little effort as possible.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
Naftuli Kay
  • 87,710
  • 93
  • 269
  • 411

5 Answers5

1

I've done it like this. You may need to easy_install pytz for timezone objects.

import pytz
import time
import datetime
d = time.time()

print datetime.datetime.fromtimestamp(d, pytz.timezone('US/Eastern'))
print datetime.datetime.fromtimestamp(d, pytz.timezone('US/Central'))
print datetime.datetime.fromtimestamp(d, pytz.timezone('US/Mountain'))
print datetime.datetime.fromtimestamp(d, pytz.timezone('US/Pacific'))

The d variable here is storing UTC time as a unix time stamp.

bigendian
  • 788
  • 4
  • 11
  • This doesn't solve the problem of knowing what timezone the user is in. – Aaron Dufour Nov 10 '11 at 23:31
  • You're right, I didn't read carefully past bringing up sites and servers. Getting time information from a web browser is typically done with Javascript. This shouldn't be trusted, but there no standard HTTP response header to convey the user's current timezone, and it's the best guess. – bigendian Nov 10 '11 at 23:39
  • In my experience, a web service to perform the conversion on clients' behalf is the most reliable solution and not too much of a headache. The service should accept/return multiple values at once to reduce the number of requests. – wberry Nov 11 '11 at 19:48
1

The problem with relying on the client to self-report their time zone is that there is always a chance (how big of a chance is debateable) that what you will really get is a UTC offset. If you get a UTC offset, your logic will work fine most of the time, but in reality will only apply to the exact timestamps produced by the client. Any past or future times may have a different UTC offset, and that can't be predicted without a proper time zone database. Near the daylight savings boundary, using UTC offsets can produce catastrophically wrong results.

Even besides that, some non-literate users (i.e. grandma) may not know how to set the time zone of their local system; or users on tunnelled sessions or virtual machines may have a "local" time zone that is not set for their actual preference.

Guessing the political time zone of the client based on what you know about that client (IP, etc) can be wrong, and can be quite annoying if there is no way for the user to override the guess. But for anonymous users or new user sign-up I see nothing wrong with using such a method as an initial guess, as long as you give the user some way to change it if it's wrong.

My recommendation would be specifically:

  • Include the Olson time zone as part of any user profile. The time zones can be looked up by country, and this should make user selection of their time zone relatively painless. Give the 0.01% of users who care the choice of straight-up UTC also :-)
  • If you populate the default in the user profile with an IP-based guess, you'll be right most of the time if you use a good lookup service. But allow the user to change it if it's wrong.
  • For anonymous users, provide some kind of widget on any page that displays or inputs local times, that lets them select their Olson time zone, in much the same way as for a user profile. Store the value they choose in a cookie. Default to UTC or to a guessed value as above.

In implementing a web-based application previously that needed to display timestamps in localized times, I found that not all clients translate UTC to local times correctly for past and future dates. I had to perform all conversions on the server side. This may necessitate a web service that takes a local time and an Olson time zone and returns a UTC time.

wberry
  • 18,519
  • 8
  • 53
  • 85
  • Perhaps I'm asking the wrong question here. Maybe I should be asking: "How does StackExchange do date conversion?" I've never had to enter a date anywhere on the site and dates seem to just appear in the right timezone, even for public users of the site. Is it really this complicated under the hood? Could you summarize what I should do in your answer? – Naftuli Kay Nov 11 '11 at 20:16
  • Well I have a `usr` cookie for stackoverflow.com with a variable `t` in it. Don't know how to decode it, but if my timezone is stored client-side anywhere that's probably it. My desktop is UTC and so are all the times this site shows me. I don't remember whether I explicitly set that TZ or not. – wberry Nov 11 '11 at 20:54
  • I just logged out and changed my desktop time zone, then visited the site. I saw UTC times. So it's either in a cookie, or my browser didn't update its idea of "local", or anonymous users always see UTC on this site. – wberry Nov 11 '11 at 21:02
  • Hmm, you're right. I guess it just strikes me as so weird that something like this is so complicated and can't be automated. – Naftuli Kay Nov 11 '11 at 21:44
  • I choose to believe that it is the time zone policies themselves that introduce unnecessary complication :-) – wberry Nov 11 '11 at 22:01
  • I read the source. It assumes that the client is able to correctly calculate UTC offsets for past and future times. Subject to that assumption, which I still feel nervous about, I agree the approach is workable. Quite clever actually. – wberry Nov 11 '11 at 22:33
  • You, sir, are a true hacker if you're proposing that the entire world switch to UTC. Hats off to you. What are the odds of a machine _not_ being able to correctly calculate UTC offsets? Give me a for-instance. – Naftuli Kay Nov 11 '11 at 22:42
  • 1
    Yeah I'm kind of a maverick that way. Regarding offsets, I worry that browsers may have some of the same issues as discussed here (though judging by the tool you found, maybe this is unlikely). http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Date.html – wberry Nov 11 '11 at 22:52
0

You can't reliably get a user's timezone from the request headers. That's why most website ask users to set their timezone in profile settings. However, you can use various tricks to try to get. One trick is to use Google's IP-to-location api to find out where the user is coming from and then try to guess the timezone from the geo location. This is not 100% reliable either, but will get you closer to the truth.

just realized this has already been asked here at least once: get user timezone

Community
  • 1
  • 1
Dmitry B.
  • 9,107
  • 3
  • 43
  • 64
0

I wouldn't do ip geolocation. It can be very inaccurate, especially free services. Just ask the user for zip code or state, and store it in cookie.

bobek
  • 8,003
  • 8
  • 39
  • 75
  • Ireland and a few other countries doesn't have zip codes. I'll take geolocation over postal details any day. – Kit Sunde Jan 10 '12 at 09:01
0

You can, using javascript (which knows the local time), change the user-inputted time to UTC before sending the data to your server. Then, send UTC down in a format such that javascript can turn it from UTC into local time.

For example, a date to UTC to be sent to the server:

(new Date("November 11, 2011 23:13:42")).toUTCString()

And UTC to local time, for rendering:

(new Date("October 17, 1986 15:29:13 UTC")).toLocaleString()
Aaron Dufour
  • 17,288
  • 1
  • 47
  • 69
  • Unless you have an Olson database available in your JavaScript VM, or you implement localization in web services, this isn't workable. – wberry Nov 10 '11 at 18:00
  • @wberry I added examples. Your browser knows what timezone it is in. I guess I don't see the problem. – Aaron Dufour Nov 10 '11 at 23:30
  • Many client implementations are flawed and will not apply daylight savings / summer time policies correctly for past and future dates. For example, if it is the day before summer time ends, and the user inputs a certain time tomorrow, in some clients the UTC time will be an hour off. Adobe Flash on Windows does this. While, as a front-end author, this is not your fault, it is your problem. – wberry Nov 11 '11 at 19:18
  • @wberry Unless you intend to ask people for their timezone, I suspect that this is the best you can do. Any time you're writing javascript code, you're assuming that the JS engine will interpret it correctly. – Aaron Dufour Nov 11 '11 at 19:45