проблемы с пониманием преобразования времени - PullRequest
0 голосов
/ 14 ноября 2018

У меня проблемы с пониманием преобразования времени в python. У меня есть два идентичных time_struct объекта

In [22]: local_dt
Out[22]: datetime.datetime(2000, 1, 1, 0, 0, tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)
In [23]: local_dt.timetuple()                                                                                                                             
Out[24]: time.struct_time(tm_year=2000, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=1, tm_isdst=0)

Когда я передаю его на функцию time.mktime на одной машине

time.mktime(local_dt.timetuple())

возвращает 946681200.0

На второй машине я получаю другой ответ

In [31]: local_dt.timetuple()                                                                                                                             
Out[31]: time.struct_time(tm_year=2000, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=1, tm_isdst=0)

In [32]: time.mktime(local_dt.timetuple())                                                                                                                
Out[32]: 946684800.0

Машины имеют разные часовые пояса:

In [44]: time.tzname                                                                                                                                      
Out[44]: ('Europe', 'Europe')

In [45]: time.tzname
Out[45]: ('CET', 'CEST')

Документация по модулю времени гласит:

Используйте следующие функции для преобразования между представлениями времени: struct_time в секундах местного времени с начала эпохи mktime ()

Как я понимаю, мое местное время - "America / Los_Angeles", поэтому секунды, начиная с эпохи, должны быть одинаковыми и не зависеть от конфигурации системы.

Что я неправильно понимаю? Как мне тогда правильно рассчитать метку времени?

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

time.mktime() интерпретирует timetuple на основе часового пояса локальной машины.Обратите внимание, что ваш timetuple объект не содержит никакой информации о часовом поясе, поэтому созданная временная метка всегда будет меняться в зависимости от часового пояса, установленного на локальном компьютере.Таким образом, совершенно понятно, почему один и тот же time.mktime(local_dt.timetuple()) возвращает различное значение на этих двух машинах.

Вместо этого вы можете использовать local_dt.timestamp(), в то время как оба по существу одинаковы ...

Наивные datetime экземплярыпредполагается, что оно представляет местное время, и этот метод использует функцию платформы C mktime() для выполнения преобразования.

... Но поскольку вы создаете timestamp непосредственно из не наивногоdatetime объект, он все еще сохраняет информацию о часовом поясе и может соответственно сдвигать время:

Для осведомленных datetime экземпляров возвращаемое значение вычисляется как:

(dt - datetime(1970, 1, 1, tzinfo=timezone.utc)).total_seconds()

Наблюдать:

>>> est = datetime.datetime(1999, 12, 31, 19, 0).astimezone(pytz.timezone('EST'))
>>> utc = est.astimezone(pytz.timezone('UTC'))
>>> est
datetime.datetime(1999, 12, 31, 19, 0, tzinfo=<StaticTzInfo 'EST'>)
>>> utc
datetime.datetime(2000, 1, 1, 0, 0, tzinfo=<UTC>)
>>> est.timestamp()
946684800.0           
>>> utc.timestamp()
946684800.0           # same as est
>>> time.mktime(est.timetuple())
946684800.0
>>> time.mktime(utc.timetuple())
946702800.0           # different than est

Последние time.mktime() обработали utc.timetuple() как местное время, так как информация о часовом поясе не была передана.Вы можете заметить, что это смещение на 18000 (time.timezone для EST, мой часовой пояс).

0 голосов
/ 14 ноября 2018

Как вы сказали: «Машины имеют разные часовые пояса, однако:» и доктор сказал: «по местному времени».

Ваше «местное время» не одинаково на обеих машинах: один - Европа /Европа (вероятно, GMT, поэтому UTC + 0), другой - CEST (UTC +1).

см. https://www.timeanddate.com/time/zones/eu

Центрально-европейское время (CET) составляет 1 часвпереди всемирного координированного времени (UTC).Этот часовой пояс используется в течение стандартного времени в: Европе, Африке.

Я думаю, что вы хотите преобразовать дату и время в "UTC + 0 datetime"

...