使用Django 1.6和PostGreSQL 9.2存储时区感知日期时间

3
TIME_ZONE = 'Europe/Paris' # UTC+1
USE_TZ = True

我希望数据库中的所有日期时间都是带有时区信息的,但是即使阅读了Django文档,我仍然不确定正确的方法是什么。

1) 首先,我尝试在所有地方使用timezone.now()。如果巴黎是12:19,它将返回:datetime.datetime(2016, 3, 16, 11, 19, 51, 842247, tzinfo=<UTC>))

这似乎是正常的行为:Django将日期时间转换为UTC,但是我不确定这是否是好事。我是否在此过程中丢失了一些数据?如何知道这些数据与巴黎时区相关联?

2) 然后,我尝试在所有地方使用localtime(timezone.now())。这次,如果巴黎是12:19,我会得到一个:datetime.datetime(2016, 3, 16, 12, 19, 37, 372710, tzinfo=<DstTzInfo 'Europe/Paris' CET+1:00:00 STD>)

这里,日期时间没有被转换,真正的时区信息(巴黎)存储在日期时间中。我认为这是更好的方法,但经过一些搜索,似乎没有人这样处理。我错过了什么吗?

此外,使用第二种解决方案,我真的希望我的对象以+01后缀存储在PostGreSQL数据库中。但是实际上并没有。这是我的数据库时间戳内容:2016-03-16 11:19:01.093176+00

我不明白如何以正确的方式完成所有这些操作。


你在系统、Django应用程序和Postgres实例中使用什么语言环境? - Eugene Lisitsky
系统(Ubuntu):“en_US”,Django:LANGUAGE_CODE = 'fr'。Postgres:没有检查,使用默认设置。不确定这是否与我的问题密切相关? - David Dahan
日期时间设置?您能在shell中执行“locale”命令吗?有时它可能会相关。 - Eugene Lisitsky
1个回答

3
文档中得知:
启用时区支持后,Django会将日期时间信息以UTC的形式存储在数据库中,内部使用有意识的带时区的datetime对象,并在模板和表单中将其转换为最终用户的时区。
因此,当您保存时间到数据库时,Django会自动将其存储为UTC。当您在模板或表单中呈现此时间时,Django会自动将其转换为用户的时区或默认时区(TIME_ZONE = 'Europe/Paris')。
这适用于Django 1.4及以上版本。 回答你的问题: Django将datetime转换为UTC,但不确定是否好。
这是一件好事,因为它提供了一致性。您现在知道所有存储在数据库中的datetime值都是以UTC格式存储的。因此,任何时间或时区操作都将非常容易,而无需考虑每个记录的时区。
我没有失去任何数据吗?如何知道数据与巴黎时区相关?
重要的是您知道时间是在哪个时区输入的吗?将时间显示在所需时区中是否足够(Django会自动这样做并将其从UTC转换为您的时区)。如果存储时区信息很重要,则需要在模型中将其存储在单独的Char类型字段中。
这里,datetime未被转换,并且实际时区信息(巴黎)存储在datetime中。我认为这样做更好,但经过一些搜索,似乎没有人这样处理。我错过了什么吗?
再次强调,当Django可以替您完成此操作时,为什么要自己这样做呢?这就是为什么没有人这样处理的原因。此外,将时间存储在标准UTC时间中是一个好习惯,以便可以轻松地转换为任何其他时区。

我知道这个,就像我说的“这似乎是正常的行为”。我也读了文档。但这并没有回答我的问题 :( - David Dahan
谢谢,现在我明白多了 :) 我想我会遵循标准的timezone.now模式。 - David Dahan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接