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

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

datetime.datetime.today()的返回值似乎不是“时区感知”,而我的其他日期值是。我如何从datetime.datetime.today()得到一个时区感知的返回值?

理想的解决方案是让它自动知道时区。

现在,它给我的时间是当地时间,恰好是PST,即UTC - 8小时。最坏的情况下,是否有一种方法我可以手动输入一个时区值到datetime.datetime.today()返回的datetime对象,并将其设置为UTC-8?


当前回答

pytz是一个Python库,允许使用Python 2.3或更高版本进行精确的跨平台时区计算。

对于stdlib,这是不可能的。

在SO上可以看到类似的问题。

其他回答

获取特定时区的当前时间:

import datetime
import pytz
my_date = datetime.datetime.now(pytz.timezone('US/Pacific'))

记得先安装pytz。

使用如下所示的时区来获得一个支持时区的日期时间。默认为UTC:

from django.utils import timezone
today = timezone.now()

下面是一个适用于Python 2和Python 3的标准库解决方案:

from datetime import datetime

now = datetime.now(utc) # Timezone-aware datetime.utcnow()
today = datetime(now.year, now.month, now.day, tzinfo=utc) # Midnight

其中today是一个感知的datetime实例,表示UTC中的一天的开始(午夜),UTC是一个tzinfo对象(示例来自文档):

from datetime import tzinfo, timedelta

ZERO = timedelta(0)

class UTC(tzinfo):
    def utcoffset(self, dt):
        return ZERO

    def tzname(self, dt):
        return "UTC"

    def dst(self, dt):
        return ZERO

utc = UTC()

相关:几种获得给定UTC时间的午夜(一天的开始)的方法的性能比较。 注意:要获得具有非固定UTC偏移量的时区的午夜,这比较复杂。

使用Python datetime.datetime.now()中描述的dateutil,它是时区感知的:

from dateutil.tz import tzlocal
# Get the current date/time with the timezone.
now = datetime.datetime.now(tzlocal())

另一个选择,在我看来是一个更好的选择,是用摆锤代替pytz。考虑下面的简单代码:

>>> import pendulum

>>> dt = pendulum.now().to_iso8601_string()
>>> print (dt)
2018-03-27T13:59:49+03:00
>>>

要安装Pendulum并查看它们的文档,请点击这里。它有大量的选项(比如简单的ISO8601, RFC3339和许多其他格式的支持),更好的性能和更简单的代码。