在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 识别出用户正在输入新加坡时间 10 月 10 日凌晨 1:00,并将其作为 2013-10-07 01:00:00+08
存储在数据库中。 但是,当 Django 从数据库中检索此信息时,它会将其格式化为 UTC 时间,从而给出2013-10-06 17:00:00+00:00
。
我有这个权利吗? 如果是这样,我该怎么做才能使用存储在数据库中的相同时区信息(或至少使用我的TIME_ZONE
设置(使 Django 显示时间? 换句话说,我怎样才能使用户以与她输入的完全相同的形式看到日期时间?
弄清楚发生了什么。 根据我在这里的文档中读到的内容,我假设使用 USE_TZ=True
,Django 会在任何地方输出当前时区(默认为TIME_ZONE
设置(的日期时间——视图、shell 等。
然而,事实证明,Django 只在模板中进行转换,即使这样,也只在对datetime
对象进行最直接、最基本的调用时进行转换。
具体来说,如果您有一个带有DateTimeField
的object
,并且您使用 {{ object.datetime }}
在模板中呈现其 datetime
属性,您将获得转换为当前时区的日期时间。 耶。但是,此功能不适用于其他任何内容,即使在模板中也是如此,例如 {{ object.datetime.hour }}
(将以 UTC 显示小时(。 所以它基本上只是一个不可见的模板标签。 没有我希望的那么神奇!
看起来我需要将所有日期时间转换为视图中的当前时区,然后再将它们传递给我的模板。 考虑到我的数据库已经将所有日期时间存储在我希望显示它们的时区中,我发现这种奇怪和违反直觉。 必须明确地告诉 Django 你想要用 UTC 表示的数据库值,而不是让 Django 自动执行工作,然后让你在视图中将它们更改回来,这不是更有意义吗?
编辑:SO上的这个答案使我的具体情况的解决方案变得相当容易:
from django.utils.timezone import localtime
result = localtime(some_time_object)
编辑:事实证明,只有PostgreSQL存储时区信息,并且该信息与它存储的原始日期时间值是分开的,这些值采用UTC。 所以我想 Django 默认以 UTC 渲染所有内容是有意义的,因为其他数据库后端甚至不存储时区信息。
你有没有看过localtime
模板标签
更新:但是,这确实是指将USE_TZ
设置为True