Django 和时区

Posted

技术标签:

【中文标题】Django 和时区【英文标题】:Django and time zone 【发布时间】:2014-12-20 21:52:40 【问题描述】:

Django 1.7,PostgreSQL。

我想以 UTC 存储日期时间并在 PST 时区显示。

我的当地时间:上午 8:05

UTC 时间:凌晨 1:05

太平洋标准时间:下午 6:05

Django 文档:

When support for time zones is enabled, Django stores date and time 
information in UTC in the database, uses time-zone-aware datetime objects 
internally, and translates them to the end user’s time zone in templates 
and forms.

setting.py

USE_TZ = True
TIME_ZONE = 'US/Pacific'

模型字段

created_at = models.DateTimeField(auto_now_add=True)

我创建了新模型,并在 django admin 中显示 PST 时间(下午 6:05)。没关系。但如果我这样做:

select created_at from my_table where id = 1;

它显示我的当地时间(上午 8:05)!所以,我不确定这是否存储在 UTC 时间。

还有一件事。

通常的日期时间字段,我在管理员中设置了这个日期:2014-10-25 18:00:00

Id 显示在 admin Oct. 25, 2014, 6 p.m.

但是从数据库中选择给我看:

2014-10-26 08:00:00.0

所以,我绝对不明白发生了什么。我的错在哪里?

【问题讨论】:

【参考方案1】:

基本上发生的情况是时间使用时间戳存储在数据库中,但使用数据库中指定的时区显示时间,除非手动更改机器的时区。但是由于您在 django 中指定了不同的时区,因此 django 会调整差异。所以你需要做的是将db中的时区更改为UTC(过程因引擎而异)

我更喜欢这样做的方式是保持数据库时区不变,在 django 设置中指定“UTC”,然后每当向用户显示时间时,使用一些 javascript 将其转换为本地用户时间。

编辑

之前没有注意到您使用的是 PostgreSQL。我认为您可以在 postgresql.conf 中更改时区或将 TimeZone 变量更改为数据库中的 UTC

【讨论】:

documentation 意味着,对于 USE_TZ = True,Django 将始终以 UTC 存储时区:“PostgreSQL 后端将日期时间存储为带有时区的时间戳。实际上,这意味着它转换日期时间从连接的时区到存储时的 UTC,从 UTC 到检索时的连接时区。”所以没有必要更改任何 PostgreSQL 设置。 其实我说错了,它确实保存了时间戳,但是每当你进行查询时,它会使用数据库设置中指定的时区显示时间。这就是为什么您必须更改设置才能看到 UTC 时区。【参考方案2】:

我认为 Alexey Kuleshevich 回答了您问题的第一部分:当您执行手册 select 时,PostgreSQL 会在数据库上配置的时区中显示时间戳。不过,这不会影响 Django,它的行为是根据文档进行的。

至于问题的第二部分:当您在表单中输入日期时间值时,Django 在 当前时区 中解释它,默认情况下与您的 TIME_ZONE 设置相同.因此,当您在管理员中输入下午 6 点时,Django 将其解释为太平洋标准时间下午 6 点,并将其存储为世界标准时间凌晨 1 点(第二天)。然后数据库将其显示为当地时间上午 8 点(第二天)。

【讨论】:

以上是关于Django 和时区的主要内容,如果未能解决你的问题,请参考以下文章

Django 中的时区

Django的时区设置问题

在 Django 模型中保存时区

Django 时间与时区设置问题

Django 时间与时区设置问题

Django:如何让 datetime 对象知道创建它的时区?