在Django中处理每个对象的时区设置

时间:2013-01-29 12:02:59

标签: django timezone

我有一个Django应用程序,用户可以在其中创建一个Activity,然后为一个Activity创建一些Log条目。 “活动”具有创建的日期时间,“日志”条目也具有创建的日期时间。

应该使用创建用户创建时的时区创建活动。具体而言,给定用户可以在不同的时区中具有两个活动;时区设置不是每个用户,但是每个活动。我可以在浏览器中从JavaScript中获取用户当前与UTC的偏移量(我很乐意依赖它)。

我不知道的是:如何将这些时间保存到数据库中,然后在渲染时正确显示它们?

我打开了USE_TZ。在英国,一切正常:创建活动时,我将创建的日期时间保存为django.utils.timezone.now(),并将用户当前的偏移量(来自JavaScript)保存为活动中的timezoneHoursOffset。然后,当我在页面上显示活动及其日志条目时,我将其包装在{% timezone "Etc/GMT+(timezoneHoursOffset)" %} ... {% endtimezone %}

但是,如果服务器不在英国,这种方法不起作用。时间以UTC格式保存在数据库中(我通过检查数据库本身验证了这一点,而不是使用ORM),然后ORM“更改”该时间比UTC晚8小时(因为服务器的时区是UTC-8)(并给出正确的时间!)然后{% timezone %}标签减去另一个 8小时的时间,这意味着显示的时间比它应该的时间晚8小时

我不确定我是否应该以不同的方式挽救时间;在输出上改变它们;使用时区模板标签;或者是其他东西。这个东西很混乱。您如何建议我处理这种情况?

2 个答案:

答案 0 :(得分:1)

参考the answer,“Etc / GMT”时区的符号相反。例如,我在+0800,它应该是'Etc/GMT-8'而不是'Etc/GMT+8'(我怀疑你的UTC-8实际应该是"Etc/GMT+8"):

>>> from django.template import Template, Context
>>> from django.utils.timezone import now
>>> print(Template("""{% load tz %}
localtime: {{ t }}
Etc/GMT-8: {{ t|timezone:"Etc/GMT-8" }}
Etc/GMT+8: {{ t|timezone:"Etc/GMT+8" }}
""").render(Context({'t':now()})))

localtime: Jan. 29, 2013, 11:48 p.m.
Etc/GMT-8: Jan. 29, 2013, 11:48 p.m.
Etc/GMT+8: Jan. 29, 2013, 7:48 a.m.

因此,您必须撤销timezoneHoursOffset ...

对于数据库存储,根据the doc,最好以UTC格式存储数据。

此外,您需要确保您的javascript因DST而生成正确的小时偏移量。如果可以的话,最好存储时区名称并相应地使用它。

答案 1 :(得分:1)

from datetime import datetime
from dateutil import zoneinfo

from_zone = zoneinfo.gettz('UTC')
to_zone = zoneinfo.gettz('UK/UK') 

utc = created # your datetime object from the db

# Tell the datetime object that it's in UTC time zone since 
# datetime objects are 'naive' by default
utc = utc.replace(tzinfo=from_zone)

# Convert time zone
eastern_time = utc.aztimezone(to_zone)