配置django的setting.TIME_ZONE会影响datetime.datetime.now()吗?

5 投票
2 回答
1807 浏览
提问于 2025-04-15 15:05

文档中提到:

http://docs.djangoproject.com/en/dev/ref/settings/#time-zone

请注意,这个时区是Django用来转换所有日期和时间的时区——不一定是服务器的时区。举个例子,一个服务器可能会运行多个Django网站,每个网站都有自己不同的时区设置。通常情况下,Django会把os.environ['TZ']这个变量设置为你在TIME_ZONE设置中指定的时区。因此,你的所有视图和模型都会自动在正确的时区下工作。

我读了好几遍,但还是不太明白TIME_ZONE设置到底是怎么回事。

如果我想让带有时间戳的模型显示用户的本地时区,我是不是需要自己管理UTC偏移量?

比如在保存的时候用datetime.datetime.utcnow()而不是datetime.datetime.now(),然后在视图中做类似这样的操作:

display_datetime = model.date_time + datetime.timedelta(USER_UTC_OFFSET)

2 个回答

1

当你的 TIME_ZONE 设置为 UTC 时,使用 utcnow()now() 得到的结果是一样的。这可能正是你想要的。这样你就可以用 nowutcnow 来记录时间,而像 timesince 这样的功能对每个用户来说都能正常工作。如果你想给特定用户显示绝对时间,可以使用你提到的 UTC 偏移量。

6

让我很惊讶的是,确实是这样。

web81:~/webapps/dominicrodger2/dominicrodger$ python2.5 manage.py shell
Python 2.5.4 (r254:67916, Aug  5 2009, 12:42:40)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import settings
>>> settings.TIME_ZONE
'Europe/London'
>>> from datetime import datetime
>>> datetime.now()
datetime.datetime(2009, 10, 15, 6, 29, 58, 85662)
>>> exit()
web81:~/webapps/dominicrodger2/dominicrodger$ date
Thu Oct 15 00:31:10 CDT 2009

是的,我在写这个回答的时候确实有点分心 :-)

我使用了 TIME_ZONE 设置,这样我在创建对象时自动添加的时间戳(使用 auto_now_add,我觉得这个功能很快就会被淘汰)会显示我设置的时区的创建时间。

如果你想把这些时间转换成你网站访问者的时区,你需要做一些额外的工作,就像你给的例子那样。如果你想频繁地进行时区转换,以便在你网站访问者的时区显示时间,我强烈建议你把 TIME_ZONE 设置为存储 UTC 时间,这样从长远来看会让你的生活更轻松(你只需要使用 UTC 偏移量,而不必担心夏令时的问题)。

如果你感兴趣,我相信时区是通过 TIME_ZONE 设置来定义的,具体可以在 这里 找到。

编辑:根据你提到的在 Windows 上不工作的评论,这个问题是因为 Django 源代码中的以下内容:

if hasattr(time, 'tzset'):
    # Move the time zone info into os.environ. See ticket #2315 for why
    # we don't do this unconditionally (breaks Windows).
    os.environ['TZ'] = self.TIME_ZONE
    time.tzset()

Windows:

C:\Documents and Settings\drodger>python
ActivePython 2.6.1.1 (ActiveState Software Inc.) based on
Python 2.6.1 (r261:67515, Dec  5 2008, 13:58:38) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> hasattr(time, 'tzset')
False

Linux:

web81:~$ python2.5
Python 2.5.4 (r254:67916, Aug  5 2009, 12:42:40)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> hasattr(time, 'tzset')
True

撰写回答