时间戳减法必须具有相同的时区或没有时区,但它们都是 UTC

roo*_*m13 5 python timezone datetime timestamp pandas

有一些问题可以解决相同的错误,TypeError: Timestamp subtraction must have the same timezones or no timezones但没有一个问题会遇到与此相同的问题。

我有 2 个 UTC 时间戳,在减去时会抛出该错误。

print(date, type(date), date.tzinfo)
>>> 2020-07-17 00:00:00+00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'> UTC
print(date2, type(date2), date2.tzinfo)
>>> 2020-04-06 00:00:00.000000001+00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'> UTC
date - date2
>>> TypeError: Timestamp subtraction must have the same timezones or no timezones
Run Code Online (Sandbox Code Playgroud)

编辑:我使用的是Python 3.6.9Pandas 1.0.1

roo*_*m13 6

检查时区类型后:type(date.tzinfo)给出<class 'datetime.timezone'>type(date2.tzinfo)给出<class 'pytz.UTC'>,因此根据 pandas 源代码,即使它们都是 UTC,它们也不被认为是相等的。

所以解决方案是让它们具有相同的tzinfo类型(pytzdatitme.timezone

这是 Github 中的一个未决问题:https ://github.com/pandas-dev/pandas/issues/32619


小智 5

有同样的问题。如果您使用 pandas 读取数据read_csv,它将使用<class 'pytz.UTC'>. 所以我的解决方案是在任何地方简单地使用相同的类。

示例代码生成错误

from datetime import datetime, timedelta, timezone
import pandas as pd

now = datetime.now(tz=timezone.utc)
some_time_ago = now - timedelta(7)

print('Timezone info before reading_csv')
print(some_time_ago.tzinfo, type(some_time_ago.tzinfo))

time_passed = now - some_time_ago
print (time_passed)

df = pd.DataFrame([some_time_ago], columns=['date'])
df.to_csv('dates.csv', index=False)

df2 = pd.read_csv('dates.csv', parse_dates=['date'])
print('\nTimezone info after reading_csv')
print(df2.iloc[0,0].tzinfo, type(df2.iloc[0,0].tzinfo))

now = datetime.now(tz=timezone.utc)
some_time_ago = now - df2.iloc[0,0]
print(some_time_ago)
Run Code Online (Sandbox Code Playgroud)
Timezone info before reading_csv
UTC <class 'datetime.timezone'>
7 days, 0:00:00

Timezone info after reading_csv
UTC <class 'pytz.UTC'>
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-23-b2815e32e8b7> in <module>
     19 
     20 now = datetime.now(tz=timezone.utc)
---> 21 some_time_ago = now - df2.iloc[0,0]
     22 print(some_time_ago)

pandas/_libs/tslibs/c_timestamp.pyx in pandas._libs.tslibs.c_timestamp._Timestamp.__sub__()

TypeError: Timestamp subtraction must have the same timezones or no timezones
Run Code Online (Sandbox Code Playgroud)

使用 pytz 正确代码

import pytz
from datetime import datetime, timedelta
import pandas as pd

now = datetime.now(tz=pytz.UTC)
some_time_ago = now - timedelta(7)

print('Timezone info before reading_csv')
print(some_time_ago.tzinfo, type(some_time_ago.tzinfo))

time_passed = now - some_time_ago
print (time_passed)

df = pd.DataFrame([some_time_ago], columns=['date'])
df.to_csv('dates.csv', index=False)

df2 = pd.read_csv('dates.csv', parse_dates=['date'])
print('\nTimezone info after reading_csv')
print(df2.iloc[0,0].tzinfo, type(df2.iloc[0,0].tzinfo))

now = datetime.now(tz=pytz.UTC)
some_time_ago = now - df2.iloc[0,0]
print(some_time_ago)
Run Code Online (Sandbox Code Playgroud)
Timezone info before reading_csv
UTC <class 'pytz.UTC'>
7 days, 0:00:00

Timezone info after reading_csv
UTC <class 'pytz.UTC'>
7 days 00:00:00.024021
Run Code Online (Sandbox Code Playgroud)