Python:如何获取“timezone aware”的datetime.today()值?

问题:

我试图从datetime.today()的值中减去一个日期值,以计算多久以前的事情。但它抱怨:

TypeError: can't subtract offset-naive and offset-aware datetimes

datetime.today()似乎不是“时区感知”,而我的其他日期值是。如何获取时区知道的datetime.today()值?现在它给了我当地时间,这恰好是PST,即UTC-8小时。最糟糕的情况是,有没有办法我可以手动输入时区值到datetime.today()返回的datetime对象,并将其设置为UTC-8?当然,理想的解决方案是让它自动知道时区。

回答:

在标准库中,没有创建自己的时区类的跨平台方式来创建感知时区。
在Windows上有win32timezone.utcnow(),但这是pywin32的一部分。我宁愿建议使用pytz library,它具有大多数时区的最新数据库。
使用本地时区可能非常棘手(阅读pytz文档!),因此您可能希望在整个应用程序中使用UTC。你可以这样得到当前的日期/时间:

import pytz
from datetime import datetime
datetime.utcnow().replace(tzinfo=pytz.utc)

注意datetime.today()datetime.now()返回local时间,而不是UTC时间,因此将.replace(tzinfo=pytz.utc)应用于它们是不正确的。
另一个很好的方法是:

datetime.now(pytz.utc)

这是一个更短,做同样的事情。
 警告:
除了UTC时间外,不要使用任何日期和时间的操作。您可能会尝试使用不同的时区做一些奇特的日期时间操作,但如果您没有注意到这一点,这可能会失败:
尝试:

d = datetime.datetime.now(pytz.timezone('America/Los_Angeles')
>>> datetime.datetime(2017, 9, 14, 22, 18, 51, 892210, 
tzinfo=<DstTzInfo 'America/Los_Angeles' PDT-1 day, 17:00:00 DST>)

# add some days to the date that is in a localized timezone
d = d + datetime.datetime.timedelta(days=90)
>>> datetime.datetime(2017, 12, 13, 22, 18, 51, 892210, 
tzinfo=<DstTzInfo 'America/Los_Angeles' PDT-1 day, 17:00:00 DST>)

这是错误的:应该是:

>>> datetime.datetime(2017, 12, 13, 21, 18, 51, 892210, 
tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 17:00:00 DST>)

因为夏令时的变化。
如果您在UTC时间内执行此操作,然后转换为本地化时区:

d = datetime.datetime.now(pytz.UTC)
>>> datetime.datetime(2017, 9, 15, 5, 34, 28, 716403, tzinfo=<UTC>)
# Add offset in UTC time
d = d + datetime.timedelta(days=90)
>>> datetime.datetime(2017, 12, 14, 5, 34, 28, 716403, tzinfo=<UTC>)
# Cast to local timezone
d.astimezone(pytz.timezone('America/Los_Angeles'))
>>> datetime.datetime(2017, 12, 13, 21, 34, 28, 716403, 
tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)

你得到正确的结果。

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: Python: How to get a value of datetime.today() that is “timezone aware”?

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

+ 88 = 96