Django似乎以UTC格式显示日期时间

时间:2013-10-02 09:50:24

标签: django datetime timezone

settings.py我有:

TIME_ZONE = 'Asia/Singapore'
USE_I18N = True
USE_L10N = True
USE_TZ = True

如果用户(居住在新加坡)在我的网站上的表单中输入2013-10-07 01:00 A.M.,则存储在我的(PostgreSQL)数据库中的值为2013-10-07 01:00:00+08。当我在python manage.py shell会话期间提取此信息时,我会收到2013-10-06 17:00:00+00:00。当我尝试在模板中呈现此信息时也会发生同样的情况。

我认为发生了什么:Django认识到用户正在进入凌晨1点。 10月10日,新加坡时间,并将其作为2013-10-07 01:00:00+08存储在数据库中。但是,当Django从数据库中检索此信息时,它会将其格式化为UTC时间,从而提供2013-10-06 17:00:00+00:00

我有这个权利吗?如果是这样,我该怎么做才能使用存储在数据库中的相同时区信息(或者至少使用我的TIME_ZONE设置)来显示Django时间?换句话说,我怎样才能让用户以与输入日期时完全相同的形式看到日期时间?

2 个答案:

答案 0 :(得分:14)

我已经知道发生了什么。根据我在文档here中所读到的内容,我假设使用USE_TZ=True,Django将在当前时区输出日期时间(默认为TIME_ZONE设置)无处不在 - 视图,shell等。

然而,事实证明Django 在模板中进行转换,即使只是在datetime对象的最直接,基本的调用中。

具体来说,如果您的object带有DateTimeField并且使用datetime在模板中呈现其{{ object.datetime }}属性,则会将日期时间转换为当前时区。好极了。但是,此功能对于任何其他功能都不起作用,即使在模板中也是如此,例如{{ object.datetime.hour }}(将以UTC显示小时)。所以它基本上只是一个不可见的模板标签。不像我希望的那样神奇!

看起来我需要将所有日期时间转换为我的视图中的当前时区,然后再将它们传递给我的模板。考虑到我的数据库已经存储在我希望它们显示的时区中的所有日期时间,我发现这种奇怪和违反直觉。如果必须明确告诉Django你是否更有意义想要以UTC表示的数据库值,而不是让Django自动执行工作,然后让你在视图中更改它们?

编辑:SO上的这个answer使解决我的具体情况变得相当容易:

from django.utils.timezone import localtime

result = localtime(some_time_object)

编辑:事实证明,只有PostgreSQL存储时区信息,并且该信息与其存储的原始日期时间值(UTC)不同。因此我认为Django默认情况下以UTC格式呈现所有内容是有道理的,因为其他数据库后端甚至不存储时区信息。

答案 1 :(得分:2)

您是否查看过localtime模板标记

更新: 但是,这确实是指将USE_TZ设置为True,因为