不能减去无偏移量和偏移量的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并在此基础上进行比较。