2015-12-02 48 views
5

我一直在python/django中大量使用日期。为了解决各种使用案例,我一直在盲目地尝试各种不同的方法,直到其中一个工作,而没有学习各种功能如何工作的逻辑。Django/python - 消除关于日期和时区感知的混淆

现在是关键时刻。我想问几个关于django/python中错综复杂的日期和时区的问题。

如何解释已有时区的datetime对象?

为了澄清,让我们说我做到以下几点:

>>> generate_a_datetime() 
datetime.datetime(2015, 12, 2, 0, 0, tzinfo=<DstTzInfo 'Canada/Eastern' LMT-1 day, 18:42:00 STD>) 
>>> 

控制台输出似乎模棱两可的对我说:

Q1)这datetime对象说,这是2015-12-02 - 什么是generate_a_datetime功能说服力我?是否说“一个站在加拿大东部的人看他的日历会看到”2015-12-02“?或是否意味着”这是“2015-12-02 UTC”......但别忘了调整这个东部加拿大时区“

django.utils.timezone.make_aware混淆了我

例如:!

>>> from django.utils import timezone 
>>> import pytz 
>>> tz = pytz.timezone('Canada/Eastern') 
>>> now_unaware = datetime.datetime.now() 
>>> now_aware_with_django = timezone.make_aware(now_unaware, tz) 
>>> now_aware_with_datetime = now_unaware.replace(tzinfo=tz) 
>>> now_unaware 
datetime.datetime(2015, 12, 2, 22, 1, 19, 564003) 
>>> now_aware_with_django 
datetime.datetime(2015, 12, 2, 22, 1, 19, 564003, tzinfo=<DstTzInfo 'Canada/Eastern' EST-1 day, 19:00:00 STD>) 
>>> now_aware_with_datetime 
datetime.datetime(2015, 12, 2, 22, 1, 19, 564003, tzinfo=<DstTzInfo 'Canada/Eastern' LMT-1 day, 18:42:00 STD>) 
>>> 

的对象now_aware_with_djangonow_aware_with_datetime似乎表现同样,但他们的控制台输出表明他们是不同的。

Q2)是什么now_aware_with_djangonow_aware_with_datetime之间的区别?

Q3)我怎么知道我是否需要使用timezone.make_awaredatetime.replace

天真的日期时间与UTC日期时间

UTC意味着是时间价值没有变化。 “天真”似乎意味着时间没有与时区相关联。

Q4)朴素和UTC日期有什么区别?看起来他们完全一样 - 既没有对实际时间值进行任何转换。

Q5)我怎么知道我什么时候想要使用天真的时间,以及何时想使用UTC时间?

如果我能得到一个答案,所有5个问题将是积极出色的。非常感谢!

回答

1

Q1)DateTime对象说,这是2015年12月2日 - 什么是generate_a_datetime功能告诉我?是否这样说:“一个站在加拿大东部的人看他的日历会看到”2015-12-02“?或者这意味着”这是2015-12-02 UTC“...但是不要忘记调整它到加拿大东部时区!“

第一种解释是正确的。该时区感知日期时间已经被“调整”为您和tzinfo只是告诉你哪个时区是在指定。

Q2)是什么now_aware_with_djangonow_aware_with_datetime之间的区别?

对于第一种情况下,你创建它代表了时间的“天真”一个相同点日期时间,而这假设天真的一次是在您的本地时区。

对于第二种情况,您说的是那个天真的人已经在您提供的时区,然后您只需粘贴tzinfo。

Q3)我怎么知道我是否需要使用timezone.make_awaredatetime.replace?

嘛,因为他们做不同的事情,你需要知道你正在试图做的知道哪些使用什么。如果你想从一个天真的时区(在你当地的时间)转换到不同的时区,你可以使用make_aware。如果你已经知道你的天真日期时间的,你只需要使用替换(或者看localizepytz,这对此任务有点小心)。

注意:通常如果你有任何天真的日期时间在第一时间徘徊,你以前做错了什么,你应该赶上更早。尝试让他们知道你的应用程序的边界 - 我会在第五季度对此进行更多的说明。

Q4)天真与UTC日期有什么区别?看起来他们完全一样 - 既没有对实际时间值进行任何转换。

一个天真的日期时间只是一个日期时间,它不告诉你它在什么时区。它不一定是UTC,它可能是任何东西。它与bytestrings和unicode相似 - 你必须知道什么是编码来说明解码的字节在说什么。对于一个天真的日期时间,你必须知道它在什么时区,然后才能说出它实际表示的时间。所以在这个意义上,UTC日期时间提供的信息比天真的日期时间更多。

UTC是协调世界时,怪怪首字母缩写的法国人。时区通常被定义为与UTC时间相差整整数小时,并且出于所有实际目的,您可以将UTC视为与UTC不同的时区0小时。这就像是GMT没有任何夏令时的废话。

Q5)我怎么知道我什么时候想要使用天真的时间,以及何时想使用UTC时间?

对此有不同意见。我的建议是始终在您的应用程序中使用UTC中的所有内容(并且仅在数据库中存储UTC!)。当任何日期时间数据输入您的应用程序时,它会进入您的应用程序,请确保它已正确转换为UTC。这也意味着,里面你的应用程序使用datetime.now()(这是一个天真的日期时间与“失踪”tzinfo应该是本地时区的机器),而不是使用datetime.utcnow()(这是一个天真的日期时间在UTC),甚至更好datetime.now(tz=pytz.utc)(这是时区知道)。

只在应用的“显示”一端更改为本地时区。您通常可以使用模板标签或甚至客户端js来做到这一点。

+0

完美。 +1为实用建议! –