无法减去时区无关和时区相关的日期时间
我在PostgreSQL中有一个带时区的timestamptz
字段。当我从表中提取数据时,我想减去现在的时间,这样就能计算出它的年龄。
我遇到的问题是,datetime.datetime.now()
和datetime.datetime.utcnow()
似乎返回的是不带时区的时间戳,这导致我出现了这个错误:
TypeError: can't subtract offset-naive and offset-aware datetimes
有没有办法避免这个问题(最好是不使用第三方模块)?
补充说明:感谢大家的建议,不过尝试调整时区似乎也会出错……所以我决定在PG中使用不带时区的时间戳,并且总是使用以下方式插入:
NOW() AT TIME ZONE 'UTC'
这样我的所有时间戳默认都是UTC(尽管这样做会更麻烦)。
12 个回答
79
我知道有些人专门用Django来简化与数据库的交互。Django提供了一些工具,可以用来实现这个功能:
from django.utils import timezone
now_aware = timezone.now()
即使你只是想用这种接口,也需要先设置一个基本的Django配置。在设置中,你需要加上USE_TZ=True
,这样才能正确处理带时区的日期时间。
光有这些可能还不足以让你觉得使用Django作为接口很有吸引力,但它还有很多其他好处。另一方面,如果你是因为搞砸了自己的Django应用而来到这里(就像我当初一样),那么这些信息或许能帮到你……
413
正确的解决办法是添加时区信息,比如在Python 3中获取当前时间作为一个带时区的日期时间对象:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
在旧版本的Python中,你可以自己定义一个utc
时区信息对象(这是来自日期时间文档的例子):
from datetime import tzinfo, timedelta, datetime
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()
然后:
now = datetime.now(utc)
470
你有没有尝试过去掉时区的相关信息?
来自 http://pytz.sourceforge.net/
naive = dt.replace(tzinfo=None)
可能还需要添加时区转换的功能。
编辑:请注意这个回答的时间。下面有一个关于在Python 3中添加时区信息,而不是去掉它的回答。 https://stackoverflow.com/a/25662061/93380