django 1.4 timezone.now() vs datetime.datetime.now()
django 1.4 timezone.now() vs datetime.datetime.now()
我对日光节约时的处理有些困惑。\nsettings.py文件中的代码如下:\n
TIME_ZONE = 'Europe/London' USE_TZ = True
\n在django shell中执行以下代码:\n
>>> from django.utils import timezone >>> import datetime >>> print timezone.now() 2012-05-28 11:19:42.897000+00:00 >>> print timezone.make_aware(datetime.datetime.now(),timezone.get_default_timez one()) 2012-05-28 12:20:03.224000+01:00
\n为什么它们在夏令时方面不一样?它们都应该是本地化感知的,不是吗?\n我已经阅读了文档,但仍然一头雾水。
在Django中,使用timezone.now()
和datetime.datetime.now()
两种方式都可以获取当前时间。然而,它们之间存在一些差异。
datetime.datetime.now()
是Python内置的方法,它返回一个不带时区信息的datetime
对象。这意味着它返回的时间是相对于服务器所在的时区的本地时间,而不是一个特定的时区。
timezone.now()
是Django提供的方法,它返回一个带有时区信息的datetime
对象。这意味着它返回的时间是相对于Django设置的时区的时间,而不是服务器所在的时区的本地时间。
这两种方法的差异主要体现在处理时间的时区问题上。如果你的应用程序需要处理多个时区的时间,或者需要确保在不同的服务器上运行时时间的一致性,那么使用timezone.now()
是更可靠的选择。
要使用datetime.datetime.now()
返回带有时区信息的时间,可以使用pytz
库。下面是一个示例:
import pytz, datetime utc = pytz.utc utc_now = datetime.datetime.now(tz=utc)
这将返回当前时间的datetime
对象,并将其设置为UTC时区。
,timezone.now()
是Django推荐的获取当前时间的方法,它可以处理时区问题并返回带有时区信息的时间。而datetime.datetime.now()
返回的时间是相对于服务器所在时区的本地时间。如果需要返回带有时区信息的时间,可以使用pytz
库来转换。
自Django 1.11开始,您可以简单地调用django.utils.timezone.localtime来获取默认时区的datetime。
>>> from django.utils import timezone >>> timezone.localtime()
从文档中可以看到:
将一个已知时区的datetime转换为不同的时区,默认为当前时区。
当省略value时,默认为now()。
这个函数不适用于无时区的datetime;请使用make_aware()代替。
这将返回2019年5月24日下午1:14。根据Windows的时间,这是下午3:14。
但是对我来说这样不起作用。它似乎返回的是UTC时间。
问题的出现原因:
Django 1.4的timezone.now()返回的是UTC时间,而不是服务器的本地时间。
解决方法:
在Django 1.11之后,可以使用django.utils.timezone.localtime()来获取默认时区的datetime。这个方法可以将已知时区的datetime转换为不同的时区,默认为当前时区。
代码示例:
from django.utils import timezone # 获取默认时区的datetime datetime_in_default_timezone = timezone.localtime() # 获取其他时区的datetime datetime_in_other_timezone = timezone.localtime(timezone.now(), timezone=timezone.get_fixed_timezone(3))
使用这种方法可以解决Django 1.4中timezone.now()返回UTC时间而不是本地时间的问题。
在Django中,有一个问题引起了很多人的困惑,即“django 1.4 timezone.now() vs datetime.datetime.now()”。这个问题的出现是因为在Django中,使用timezone.now()返回的时间是基于UTC而不是默认时区。这导致了在使用datetime.datetime.now()进行比较时出现了错误。
根据timezone.now()的源码,可以看到它根据settings.USE_TZ的设置返回一个带有时区信息或者没有时区信息的datetime.datetime对象。如果USE_TZ为True,它会返回一个基于UTC的datetime对象;如果USE_TZ为False,它会返回一个没有时区信息的datetime对象。
为了解决这个问题,可以使用以下代码来获得与timezone.now()相同的值:
now = timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone()) print now.astimezone(timezone.utc)
这种解决方法可能有些反直觉,因为人们通常认为timezone.now()会返回默认时区的当前时间。但是使用.astimezone()方法可以解决这个问题。
另外,上述问题还可以在was_published_recently方法中使用timezone.now()代替datetime.datetime.now()来解决。这是因为Django在处理时间时会将其保持为UTC时间,直到需要将其呈现给用户。这就是为什么在模板标签中使用now时会自动进行转换的原因。
总结起来,问题的出现是因为timezone.now()返回的时间是基于UTC而不是默认时区,解决方法是使用.astimezone()方法进行转换或者在相关方法中使用timezone.now()代替datetime.datetime.now()。这个问题可能有些反直觉,但是理解了Django处理时间的机制后就能够解决这个问题。