1

我目前一直以 UTC 存储时间,以便在我开始将多个站点和服务器联机时使事情变得更容易。

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

如何以一种聪明、不易出错的方式正确翻译这些值?有没有一种方法可以从 HTTP 请求中确定用户所在的时区?我真的需要一种方法来尽可能少地确定用户的时区。

4

5 回答 5

1

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

于 2011-11-10T05:08:14.307 回答
1

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

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

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

我的建议是:

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

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

于 2011-11-11T19:43:28.777 回答
0

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

刚刚意识到这已经在这里至少被问过一次:获取用户时区

于 2011-11-10T04:43:03.530 回答
0

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

于 2011-11-10T04:57:15.100 回答
0

您可以使用 javascript(知道本地时间)将用户输入的时间更改为 UTC,然后再将数据发送到您的服务器。然后,以某种格式发送 UTC,以便 javascript 可以将其从 UTC 转换为本地时间。

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

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

和 UTC 到本地时间,用于渲染:

(new Date("October 17, 1986 15:29:13 UTC")).toLocaleString()
于 2011-11-10T07:03:35.090 回答