Python datetime 和 pandas 对于相同日期提供不同的时间戳

4
from datetime import datetime
import pandas as pd

date="2020-02-07T16:05:16.000000000"

#Convert using datetime
t1=datetime.strptime(date[:-3],'%Y-%m-%dT%H:%M:%S.%f')

#Convert using Pandas
t2=pd.to_datetime(date)

#Subtract the dates
print(t1-t2)

#subtract the date timestamps
print(t1.timestamp()-t2.timestamp())

在这个例子中,我的理解是datetime和pandas都应该使用时区无关的日期。有人可以解释为什么日期之间的差异为零,但时间戳之间的差异不为零吗?对我来说它的偏差是5小时,这是我与GMT的时区偏差。

1
警告:由于许多日期时间方法将天真的日期时间对象视为本地时间,因此最好使用明确的日期时间来表示UTC时间。因此,表示特定UTC时间戳的对象的推荐方法是通过调用datetime.fromtimestamp(timestamp,tz = timezone.utc)来创建。 - Scott Boston
1
https://docs.python.org/3/library/datetime.html#timezone-objects - Scott Boston
1
本地日期时间会返回一个带有您所在时区意识的时间。 - Scott Boston
1个回答

1
Python的datetime.datetime类的Naive datetime对象代表本地时间。这在文档中是显而易见的,但仍然可能会让人感到困惑。如果您在其上调用timestamp方法,则返回的POSIX时间戳应该是UTC(自纪元以来的秒数)。
从Python datetime对象转换而来,一个naive的pandas.Timestamp的行为可能不太直观(我认为这并不是那么明显)。同样是从tz-naive字符串派生出来的,它不代表当地时间,而是UTC。您可以通过将datetime对象本地化到UTC来验证。
from datetime import datetime, timezone
import pandas as pd

date = "2020-02-07T16:05:16.000000000"

t1 = datetime.strptime(date[:-3], '%Y-%m-%dT%H:%M:%S.%f')
t2 = pd.to_datetime(date)

print(t1.replace(tzinfo=timezone.utc).timestamp() - t2.timestamp())
# 0.0

另一种方法是使 pandas.Timestamp 具有时区意识,例如:
t3 = pd.to_datetime(t1.astimezone())
# e.g. Timestamp('2020-02-07 16:05:16+0100', tz='Mitteleuropäische Zeit')

# now both t1 and t3 represent my local time:
print(t1.timestamp() - t3.timestamp())
# 0.0

我的底线是,如果你知道你所拥有的时间戳代表特定的时区,请使用时区感知的日期时间,例如UTC。
import pytz # need to use pytz here since pandas uses that internally

t1 = datetime.strptime(date[:-3], '%Y-%m-%dT%H:%M:%S.%f').replace(tzinfo=pytz.UTC)
t2 = pd.to_datetime(date, utc=True)

print(t1 == t2)
# True
print(t1-t2)
# 0 days 00:00:00
print(t1.timestamp()-t2.timestamp())
# 0.0

谢谢你的详细解释,现在我明白了。我之前没有意识到 tz=None 的 datetime 对象会自动适应本地时区。 - Dan
@Dan:嗯,天真的datetime对象表示本地时间,但有点不知情 - 无论如何,很高兴我能帮忙;-) - FObersteiner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接