Python 3: установите метку времени к дате и времени: куда этот дополнительный час прибывает из?

Я использую следующие функции:

# The epoch used in the datetime API.
EPOCH = datetime.datetime.fromtimestamp(0)

def timedelta_to_seconds(delta):
    seconds = (delta.microseconds * 1e6) + delta.seconds + (delta.days * 86400)
    seconds = abs(seconds)

    return seconds

def datetime_to_timestamp(date, epoch=EPOCH):
    # Ensure we deal with `datetime`s.
    date = datetime.datetime.fromordinal(date.toordinal())
    epoch = datetime.datetime.fromordinal(epoch.toordinal())

    timedelta = date - epoch
    timestamp = timedelta_to_seconds(timedelta)

    return timestamp

def timestamp_to_datetime(timestamp, epoch=EPOCH):
    # Ensure we deal with a `datetime`.
    epoch = datetime.datetime.fromordinal(epoch.toordinal())

    epoch_difference = timedelta_to_seconds(epoch - EPOCH)
    adjusted_timestamp = timestamp - epoch_difference

    date = datetime.datetime.fromtimestamp(adjusted_timestamp)

    return date

И использование их с переданным кодом:

twenty = datetime.datetime(2010, 4, 4)

print(twenty)
print(datetime_to_timestamp(twenty))
print(timestamp_to_datetime(datetime_to_timestamp(twenty)))

И получение следующих результатов:

2010-04-04 00:00:00
1270339200.0
2010-04-04 01:00:00

По некоторым причинам я добавлял дополнительный час в последней возможности, несмотря на мое наличие кода, насколько я вижу, никакие дефекты.

Куда этот дополнительный час прибывает из?

7
задан Humphrey Bogart 5 April 2010 в 23:52
поделиться

2 ответа

# Ensure we deal with `datetime`s.
date = datetime.datetime.fromordinal(date.toordinal())

(Это полностью отбрасывает время суток, поскольку «порядковый номер» - это всего лишь номер дня. Это то, что вы имели в виду Я подозреваю, что нет.)

В любом случае, как сказал Майкл, datetime.fromtimestamp дает вам наивное datetime, соответствующее локальному времени для этой отметки времени POSIX (UTC). для тебя. Поэтому, когда вы вызываете -

date = datetime.datetime.fromtimestamp(adjusted_timestamp)

, вы получаете местное время для отметки времени POSIX, представляющей 2010-04-04T00: 00: 00, что, конечно же, в BST на час вперед. В обратном направлении этого не происходит, потому что ваша эпоха - январь, когда BST не действует. (Однако ваш EPOCH также был бы полностью отключен, если бы вы не были в Великобритании.)

Вам следует заменить оба ваших использования datetime.fromtimestamp на datetime. utcfromtimestamp .

Печально, что datetime продолжает ужасную традицию time сохранения времени по местному времени. Называя их «наивными» и убирая флаг летнего времени, им становится только хуже. Лично я терпеть не могу использовать datetime , предпочитая целочисленные временные метки UTC для всего (преобразование в локальные часовые пояса только для форматирования).

4
ответ дан 7 December 2019 в 12:17
поделиться

Судя по вашему профилю, вы находитесь в Великобритании. Это означает, что вы сейчас работаете в UTC + 1 из-за летнего времени.

Если я возьму вашу временную метку и пропущу ее через datetime.fromtimestamp на Python 2.6 (я знаю, что вы используете Python 3, но это то, что у меня есть), это покажет мне, что он считает, что это относится к 2010-04-04 02: 00:00 - и я в CEST, так что это UTC + 2.

Запустив datetime.fromtimestamp (0), я понял, что эпоха 1970-01-01 01:00:00. Затем это показывает мне, что он правильно добавляет только один час (поскольку 1 января находится за пределами летнего времени, а эпоха - полночь по всемирному координированному времени в эту дату, здесь будет 01:00).

Другими словами, ваша проблема в том, что вы отправляете время, к которому применяется летнее время, но datetime_to_timestamp обрабатывает его так, как если бы летнего времени не существовало. timestamp_to_datetime, однако, применяет летнее время.

К сожалению, я недостаточно знаю Python, чтобы знать, как вы решите эту проблему, но это должно, по крайней мере, дать вам кое-что, чтобы продолжить.

1
ответ дан 7 December 2019 в 12:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: