Django时区支持让我感到困惑

3

我是一名初学者,需要进行Django相关的翻译。

官方文档中写道:

# Support for time zones is enabled in the default settings file, so
# Django expects a datetime with tzinfo for pub_date. Use timezone.now()
# instead of datetime.datetime.now() and it will do the right thing.
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())

尝试在./manage.py shell中重现:

In [35]: from django.conf import settings

In [36]: settings.USE_TZ
Out[36]: True

In [37]: settings.TIME_ZONE
Out[37]: 'Europe/Moscow'

In [38]: from django.utils import timezone

    # UTC
In [39]: timezone.now()
Out[39]: datetime.datetime(2015, 10, 16, 9, 47, 50, 755418, tzinfo=<UTC>)

    # Actual time
In [40]: timezone.datetime.now()
Out[40]: datetime.datetime(2015, 10, 16, 12, 47, 54, 554197)

    # UTC
In [41]: timezone.activate("Europe/Moscow"); timezone.now()
Out[41]: datetime.datetime(2015, 10, 16, 9, 47, 59, 405269, tzinfo=<UTC>)

    # Actual time
In [42]: timezone.activate("Europe/Moscow"); timezone.datetime.now()
Out[42]: datetime.datetime(2015, 10, 16, 12, 48, 3, 179085)

当我按照文档中指定的方式运行timezone.now()时,我得到了错误的UTC时间。当我运行timezone.datetime.now()(我认为这只是调用datetime.datetime.now(),它使用系统范围内的时区)时,我得到了正确的时间。

尝试了不同的时区,仍然得到了纯UTC时间。

我做错了什么?

1个回答

2

timezone.now() 是一个与时区有关的函数,如果 USE_TZ=True,它会返回一个已经转换为 UTC 时区的当前时间。

例如,2015-10-16 09:47:50+00:00 (UTC)2015-10-16 12:47:50+03:00 (MSK) 是同一时刻。在模板中,UTC 时间会根据你的当前时区进行渲染(默认使用 TIME_ZONE 设置),因此无需使用 timezone.activate() 显式设置时区。

如果需要,可以使用 timezone.localtime(timezone.now()) 显式获取本地时间(但通常不需要这样做)。


很奇怪,我认为settings.USE_TZ设置的目的是自动转换为TIME_ZONE。如果我理解正确,那么USE_TZ=True以某种方式提供了将时区信息“注入”到timezone.now()对象中的方法。我是对的吗? - mkurnikov
2
@mkurnikov:这并不奇怪:最佳实践:在任何地方使用UTC,为显示转换为本地时间:这正是Django所做的。要理解为什么如果可能应该优先处理UTC,请考虑例如,您如何查找两个日期时间之间是否已经过去了24小时 - jfs
好的,现在我明白了。谢谢你的回答。 - mkurnikov

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