Django/python-消除日期和时区意识方面的混淆
我一直在python/django中广泛使用Date。为了解决各种用例,我一直在盲目地尝试各种不同的方法,直到其中一种有效,而没有学习各种功能如何工作背后的逻辑 现在是关键时刻。我想问几个关于django/python中复杂的日期和时区的问题 如何解释已经有时区的Django/python-消除日期和时区意识方面的混淆,python,django,datetime,pytz,Python,Django,Datetime,Pytz,我一直在python/django中广泛使用Date。为了解决各种用例,我一直在盲目地尝试各种不同的方法,直到其中一种有效,而没有学习各种功能如何工作背后的逻辑 现在是关键时刻。我想问几个关于django/python中复杂的日期和时区的问题 如何解释已经有时区的datetime对象? 为了澄清,假设我做了以下工作: >>> generate_a_datetime() datetime.datetime(2015, 12, 2, 0, 0, tzinfo=<DstTzIn
datetime
对象?
为了澄清,假设我做了以下工作:
>>> generate_a_datetime()
datetime.datetime(2015, 12, 2, 0, 0, tzinfo=<DstTzInfo 'Canada/Eastern' LMT-1 day, 18:42:00 STD>)
>>>
对象now\u aware\u with_django
和now\u aware\u with_datetime
的行为似乎类似,但它们的控制台输出表明它们是不同的
问题2)带有django的now\u aware\u与带有datetime的now\u aware\u之间有什么区别
问题3)我如何知道我是否需要使用时区。使您知道或日期时间。替换
原始日期时间与UTC日期时间的比较
UTC
表示时间值没有变化。“天真”似乎意味着时间没有与之相关的时区
问题4)naive和UTC日期时间之间有什么区别?看起来它们是完全一样的——既没有对实际时间值施加任何转换
问题5)我如何知道何时要使用naive Time,何时要使用UTC Time
如果我能得到所有5个问题的答案,那将是非常棒的。非常感谢 Q1)这个datetime对象表示这是2015-12-02-generate_a_datetime函数告诉我什么?是说“一个站在加拿大东部看日历的人看到了“2015-12-02”?还是说“这是“2015-12-02 UTC”。。。但别忘了将其调整到加拿大东部时区!“
第一种解释是正确的。时区感知日期时间已经为您“调整”,tzinfo只是告诉您指定的时区
Q2)使用django的now\u aware\u与使用datetime的now\u aware\u有何不同
对于第一种情况,您正在创建一个datetime,它表示与“naive”时间点相同的时间点,并且假设naive时间点位于您的本地时区
对于第二种情况,您说天真的一个已经在您提供的时区内,然后您只需添加tzinfo
Q3)我如何知道我是否需要使用时区。知道或日期时间。替换?
好吧,因为它们做不同的事情,你需要知道你在尝试做什么来知道使用哪一个。如果你想从一个原始时区(在你的本地时间)转换到另一个时区,你可以使用make_aware
。如果你已经知道原始日期时间的时区,你只需要使用replace(或者查看pytz
中的localize
,这项任务会更加小心)
注意:通常,如果你一开始就有一些天真的约会时间,那么你在早些时候就做错了什么,你应该早点发现。试着让他们在你的应用程序的边界上意识到这一点-我会在Q5中对此进行详细说明
Q4)naive和UTC datetimes之间有什么区别?它们似乎完全相同-既不强制对实际时间值进行任何转换。
一个简单的datetime只是一个datetime,它不告诉你它在哪个时区。它不一定是UTC,它可以是任何东西。它类似于bytestrings和unicode——你必须知道编码是什么,才能说出解码的字节在说什么。对于一个简单的datetime,你必须知道它在哪个时区,然后才能说出我的时间因此,在这个意义上,UTC日期时间提供的信息比简单的日期时间更多
UTC是协调世界时,奇怪的首字母缩写应该归咎于法国人。时区通常被定义为与UTC相差整数小时,出于所有实际目的,你可以将UTC视为与UTC相差0小时的时区。它就像GMT一样,没有任何夏令时的废话
Q5)我如何知道何时要使用原始时间,何时要使用UTC时间?
对此有不同的看法。我的建议是始终在应用程序中使用UTC中的所有内容(并且也只在数据库中存储UTC!)。当任何日期时间数据进入你的应用程序时,无论它进入你的应用程序的方式如何,请确保它正确转换为UTC。这也意味着,在你的应用程序中使用datetime.now()
(这是一个带有“缺少”tzinfo的原始日期时间,应该是机器的本地时区)的任何地方都使用datetime.utcnow()
(在UTC中这是一个简单的日期时间)或者更好的datetime.now(tz=pytz.UTC)
(它是时区感知的)
仅在应用程序的“显示”端更改为本地时区。您通常可以使用模板标签,甚至使用客户端js来执行此操作。Perfect.+1获得实用建议!
>>> 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>)
>>>