不能减去无偏移量和偏移量的date时间
我在PostgreSQL中有一个时区感知timestamptz
字段。 当我从表格中提取数据时,我现在想减去时间,这样我就可以得到它的年龄。
我遇到的问题是, datetime.datetime.now()
和datetime.datetime.utcnow()
似乎返回时区不知道的时间戳,这导致我得到这个错误:
TypeError: can't subtract offset-naive and offset-aware datetimes
有没有办法避免这种情况(最好没有使用第三方模块)。
编辑:感谢您的build议,但试图调整时区似乎给我的错误..所以我只是要在PG中使用时区未知的时间戳,并始终插入使用:
NOW() AT TIME ZONE 'UTC'
这样,我所有的时间戳都默认是UTC(即使这样做更麻烦)。
你有没有尝试删除时区意识?
来自http://pytz.sourceforge.net/
naive = dt.replace(tzinfo=None)
可能还需要添加时区转换。
编辑:请注意这个答案的年龄。 Python 3的答案如下。
正确的解决scheme是添加时区信息,例如,获取当前时间作为Python 3中的一个知晓的date时间对象:
from datetime import datetime, timezone now = datetime.now(timezone.utc)
在较老的Python版本上,你可以自己定义utc
tzinfo对象(例如datetime文档):
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)
我知道有些人专门用Django作为一个接口来抽象这种types的数据库交互。 Django提供了可用于此的实用程序:
from django.utils import timezone now_aware = timezone.now()
即使您只是使用这种types的界面(在设置中,您需要包含USE_TZ=True
以获得知晓的date时间),您也需要设置基本的Django设置基础结构。
就其本身而言,这可能远不足以激发你使用Django作为接口,但还有许多其他的特性。 另一方面,如果你偶然在这里,因为你正在修改你的Django应用程序(就像我这样做),那么也许这有助于…
这是一个非常简单明了的解决scheme
两行代码
# First we obtain de timezone info o some datatime variable tz_info = your_timezone_aware_variable.tzinfo # Now we can subtract two variables using the same time zone info # For instance # Lets obtain the Now() datetime but for the tz_info we got before diff = datetime.datetime.now(tz_info)-your_timezone_aware_variable
你必须用相同的时间信息来pipe理你的date时间variables
psycopg2模块有自己的时区定义,所以我最终围绕utcnow写了自己的包装:
def pg_utcnow(): import psycopg2 return datetime.utcnow().replace( tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=0, name=None))
只要使用pg_utcnow
只要你需要当前的时间来比较一下PostgreSQL的timestamptz
我也面临同样的问题。 然后,我经过了很多search后find了一个解决scheme。
问题是,当我们从模型或表单中获取date时间对象时,它是偏移量感知的 ,如果我们通过系统获取时间,则它是偏移天真的 。
所以我所做的是使用timezone.now()获取当前时间,并从django.utils导入时区导入时区 ,并将USE_TZ = True放入您的项目设置文件中。
有没有一些压力的原因,你为什么不能在PostgreSQL中处理年龄计算? 就像是
select *, age(timeStampField) as timeStampAge from myTable
我知道这是旧的,但只是想我会添加我的解决scheme,以防万一有人认为它有用。
我想比较本地天真的date时间与从时间服务器知道的date时间。 我基本上创build一个新的朴素的date时间对象使用意识的date时间对象。 这是一个黑客,看起来不漂亮,但完成工作。
import ntplib import datetime from datetime import timezone def utc_to_local(utc_dt): return utc_dt.replace(tzinfo=timezone.utc).astimezone(tz=None) try: ntpt = ntplib.NTPClient() response = ntpt.request('pool.ntp.org') date = utc_to_local(datetime.datetime.utcfromtimestamp(response.tx_time)) sysdate = datetime.datetime.now()
…这里来的巧克力…
temp_date = datetime.datetime(int(str(date)[:4]),int(str(date)[5:7]),int(str(date)[8:10]),int(str(date)[11:13]),int(str(date)[14:16]),int(str(date)[17:19])) dt_delta = temp_date-sysdate except Exception: print('Something went wrong :-(')
我发现timezone.make_aware(datetime.datetime.now())
在django(我在1.9.1)是有帮助的。 不幸的是,你不能简单地使datetime
对象偏移感知,然后timetz()
它。 你必须做一个datetime
并在此基础上进行比较。