时区与本地化
我现在把所有的时间都存储为协调世界时(UTC),这样在我开始上线多个网站和服务器的时候会更方便。
问题在于,当我把 date
和 datetime
对象转换成字符串在我的模板中显示,或者在接受用户输入的时候,6:00PM UTC 对于在太平洋标准时间(PST)的人来说并没有太大意义。同样,让用户输入 UTC 时间简直就是在制造麻烦。
我该如何以一种聪明且不容易出错的方式正确转换这些值呢?有没有办法从 HTTP 请求中判断用户所在的时区?我真的需要一种方法来尽量少花力气就能确定用户的时区。
5 个回答
你不能完全依靠请求头来获取用户的时区。这就是为什么大多数网站会让用户在个人设置中自己选择时区。不过,你可以用一些小技巧来尝试获取这个信息。其中一个方法是使用谷歌的IP定位API,看看用户是从哪里来的,然后根据这个地理位置来猜测时区。这种方法也不是百分之百准确,但能让你更接近真实情况。
我刚意识到这个问题之前已经在这里被问过至少一次:获取用户时区
我这样做过。你可能需要用easy_install来安装pytz这个库,以便使用时区对象。
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'))
这里的d变量存储的是以Unix时间戳形式表示的UTC时间。
依赖用户自己报告他们的时区是有问题的,因为总有可能(这个可能性有多大可以讨论)你得到的其实是UTC偏移量。如果你得到的是UTC偏移量,你的逻辑在大多数情况下是能正常工作的,但实际上只适用于用户提供的确切时间戳。任何过去或未来的时间可能会有不同的UTC偏移量,而没有一个合适的时区数据库是无法预测的。在夏令时的边界附近,使用UTC偏移量可能会导致非常严重的错误结果。
除此之外,一些不太懂技术的用户(比如奶奶)可能不知道如何设置他们本地系统的时区;或者在隧道会话或虚拟机上的用户,他们的“本地”时区可能并不是他们实际想要的。
根据你对用户(比如IP等)的了解来猜测他们的政治时区可能会出错,如果用户没有办法更改这个猜测,那就会很烦人。不过对于匿名用户或新用户注册,我觉得用这种方法作为初步猜测是可以的,只要给用户提供一些方式来更改它,如果猜错了。
我的具体建议是:
- 在用户资料中包含Olson时区。可以通过国家来查找时区,这样用户选择时区会相对简单。也给那0.01%在意的用户提供直接选择UTC的选项 :-)
- 如果你在用户资料中用基于IP的猜测来填充默认值,如果你使用一个好的查找服务,大多数情况下是对的。但如果猜错了,允许用户更改。
- 对于匿名用户,在任何显示或输入本地时间的页面上提供某种小工具,让他们选择自己的Olson时区,和用户资料的方式类似。把他们选择的值存储在cookie中。默认设置为UTC或上面提到的猜测值。
在之前实现一个需要显示本地时间戳的网页应用时,我发现并不是所有客户端都能正确将UTC转换为过去和未来的本地时间。我不得不在服务器端进行所有转换。这可能需要一个网络服务,接受本地时间和Olson时区,并返回UTC时间。