Time zones and Localisation

2019-02-20 15:30发布

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.

5条回答
Animai°情兽
2楼-- · 2019-02-20 15:33

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

查看更多
迷人小祖宗
3楼-- · 2019-02-20 15:33

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.

查看更多
The star\"
4楼-- · 2019-02-20 15:43

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.

查看更多
Rolldiameter
5楼-- · 2019-02-20 15:43

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()
查看更多
我欲成王,谁敢阻挡
6楼-- · 2019-02-20 15:56

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.

查看更多
登录 后发表回答