Python datetime и pandas дают разные временные метки для одной и той же даты

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 ответ

Решение

Наивные объекты datetime, производные от Python datetime.datetimeкласс представляют местное время. Это отчасти очевидно из документации, но тем не менее может быть головоломкой для работы. Если вы позвоните вtimestamp метода на нем, возвращенная метка времени POSIX относится к UTC (секунды с эпохи), как и должно.

Исходя из объекта Python datetime, поведение наивного pandas.Timestampможет быть нелогичным (и я думаю, что это не так очевидно). Полученный таким же образом из tz-наивной строки, он не представляет местное время. Это относится к UTC, если вы называетеtimestampметод. В этом можно убедиться, локализовав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')

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
Другие вопросы по тегам