Python 时区和本地化

Python 时区和本地化,python,django,timezone,python-datetime,Python,Django,Timezone,Python Datetime,目前,我将所有时间都存储在UTC中,以便在我开始将多个站点和服务器联机时更方便 在我的模板中将date和datetime对象转换为字符串以及接受用户输入时会出现问题。下午6:00 UTC对PST的人来说意义不大。同样,要求用户在UTC中输入时间也是在要求灾难 如何以一种智能的、不易出错的方式正确转换这些值?有没有一种方法可以从HTTP请求中确定用户所在的时区?我真的需要一种尽可能省力地确定用户时区的方法 您无法从请求头可靠地获取用户的时区。这就是为什么大多数网站要求用户在配置文件设置中设置时区。

目前,我将所有时间都存储在UTC中,以便在我开始将多个站点和服务器联机时更方便

在我的模板中将
date
datetime
对象转换为字符串以及接受用户输入时会出现问题。下午6:00 UTC对PST的人来说意义不大。同样,要求用户在UTC中输入时间也是在要求灾难


如何以一种智能的、不易出错的方式正确转换这些值?有没有一种方法可以从HTTP请求中确定用户所在的时区?我真的需要一种尽可能省力地确定用户时区的方法

您无法从请求头可靠地获取用户的时区。这就是为什么大多数网站要求用户在配置文件设置中设置时区。但是,您可以使用各种技巧来尝试获取。一个技巧是使用谷歌的IP-to-location api找出用户来自何处,然后尝试根据地理位置猜测时区。这也不是100%可靠,但会让你更接近真相


刚刚意识到这里已经有人问过至少一次了:

我不会做ip地理定位。它可能非常不准确,尤其是免费服务。只需向用户询问邮政编码或州,然后将其存储在cookie中

我是这样做的。您可能需要为时区对象轻松安装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变量将UTC时间存储为unix时间戳。

在将数据发送到服务器之前,可以使用javascript(知道本地时间)将用户输入的时间更改为UTC。然后,以一种javascript可以将UTC转换为本地时间的格式发送UTC

例如,要发送到服务器的UTC日期:

(new Date("November 11, 2011 23:13:42")).toUTCString()
和UTC到本地时间,用于渲染:

(new Date("October 17, 1986 15:29:13 UTC")).toLocaleString()

依赖客户自行报告其时区的问题在于,始终存在一个机会(机会有多大是有争议的),即您真正得到的是UTC偏移量。如果获得UTC偏移量,您的逻辑在大多数情况下都可以正常工作,但实际上只适用于客户机生成的准确时间戳。任何过去或未来的时间都可能有不同的UTC偏移量,如果没有适当的时区数据库,这是无法预测的。在夏令时边界附近,使用UTC偏移可能会产生灾难性的错误结果

除此之外,一些不识字的用户(如奶奶)可能不知道如何设置本地系统的时区;或者,隧道会话或虚拟机上的用户可能有一个“本地”时区,该时区不是为他们的实际偏好设置的

根据您对该客户机(IP等)的了解猜测该客户机的政治时区可能是错误的,如果用户无法覆盖该猜测,则可能会非常恼人。但是对于匿名用户或新用户注册,我认为使用这种方法作为初始猜测没有什么错,只要你给用户一些方法来改变它,如果它是错误的

我的建议具体如下:

  • 将奥尔森时区作为任何用户配置文件的一部分。时区可以按国家查找,这将使用户选择时区相对轻松。还应让0.01%关心直接向上UTC选择的用户:-)
  • 如果使用基于IP的猜测填充用户配置文件中的默认值,那么如果使用良好的查找服务,大多数情况下都是正确的。但是如果错误,允许用户更改它
  • 对于匿名用户,在显示或输入本地时间的任何页面上提供某种小部件,让他们选择自己的奥尔森时区,方式与用户配置文件大致相同。将他们选择的值存储在cookie中。默认值为UTC或上述猜测值

在实现以前需要以本地化时间显示时间戳的基于web的应用程序时,我发现并不是所有客户机都能正确地将UTC转换为本地时间来表示过去和未来的日期。我必须在服务器端执行所有转换。这可能需要一个使用本地时间和奥尔森时区并返回UTC时间的web服务。

除非JavaScript VM中有奥尔森数据库,或者在web服务中实现本地化,否则这是不可行的。@WBERY I添加了示例。你的浏览器知道它所在的时区。我想我看不出问题所在。许多客户端实现都有缺陷,无法在过去和将来的日期正确应用夏令时/夏令时策略。例如,如果是夏季时间结束的前一天,并且用户输入明天的某个时间,则在某些客户机中UTC时间将为一小时。Windows上的Adobe Flash可以做到这一点。然而,作为一名前端作者,这不是你的错,而是你的问题。@wberry除非你打算询问人们的时区,否则我怀疑这是你能做的最好的了。无论何时编写javascript代码,您都假设JS引擎将正确解释代码。这并不能解决知道用户所在时区的问题。没错,我没有仔细阅读关于站点和服务器的内容。从web浏览器获取时间信息通常是通过Javascript完成的。这不应该被信任,但是没有标准的HTTP响应头来传递用户的当前时区,这是最好的猜测。根据我的经验,代表客户端执行转换的web服务是最可靠的解决方案,也不太令人头痛。服务应该一次接受/返回多个值以减少请求的数量。也许我在这里问的问题不对。也许我应该问:“StackExchange是如何进行日期转换的?”我从来没有在网站上的任何地方输入过日期,而且日期似乎正好出现在正确的时区,即使对于网站的公共用户也是如此。引擎盖下真的这么复杂吗?你能在你的回答中总结一下我应该做什么吗?我有