Разница между сложением времени с использованием метки времени и использованием метки времени? - PullRequest
0 голосов
/ 14 мая 2018

Я работаю над проблемой Exercism.io gigasecond:

"Рассчитать момент, когда кто-то прожил 10 ^ 9 секунд."

Мой метод заключался в преобразовании ввода даты и времени вотметку времени, добавьте 10 ** 9, а затем выполните обратное преобразование.Мои ответы очень близки, но набор тестов (предоставляемый Exercism) терпит неудачу, потому что часовой аргумент выключен одним.Все остальные аргументы верны.

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

Мой вопрос: почему существует разница в результатах этих двух методов?Как вы можете видеть ниже, проблема проявляется только тогда, когда входной аргумент для часа равен значению по умолчанию 0.

Код:

def add_gigasecond(birth_date):
    gigadate = birth_date.timestamp() + 10**9
    print(datetime.fromtimestamp(gigadate).__repr__())

    gigadate = birth_date + timedelta(seconds=10**9)
    print(gigadate.__repr__())

Входные данные:

tests = [datetime(2011, 4, 25),
         datetime(1977, 6, 13),
         datetime(1959, 7, 19),
         datetime(2015, 1, 24, 22, 0, 0),
         datetime(2015, 1, 24, 23, 59, 59),]

Результаты:

test 1
datetime.datetime(2043, 1, 1, 0, 46, 40)
datetime.datetime(2043, 1, 1, 1, 46, 40)

test 2
datetime.datetime(2009, 2, 19, 0, 46, 40)
datetime.datetime(2009, 2, 19, 1, 46, 40)

test 3
datetime.datetime(1991, 3, 27, 0, 46, 40)
datetime.datetime(1991, 3, 27, 1, 46, 40)

test 4
datetime.datetime(2046, 10, 2, 23, 46, 40)
datetime.datetime(2046, 10, 2, 23, 46, 40)

test 5
datetime.datetime(2046, 10, 3, 1, 46, 39)
datetime.datetime(2046, 10, 3, 1, 46, 39)

Как видно, верхний ответ в каждом тесте (с использованием временных отметок) отключен на 1 для всех входных данных, в которых указаны год, месяц и дата.Правильный ответ достигается, когда во вход вводятся аргументы часа, минуты, секунды и микросекунды.

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

Летнее время

Некоторые детективные работы могут пролить свет на эти проблемы.Для этого расследования я выберу первую дату в вашем списке, 25 апреля 2011 года.

from datetime import datetime, timedelta

def add_seconds(birth_date, n):
    x = datetime.fromtimestamp(birth_date.timestamp() + n)
    y = birth_date + timedelta(seconds=n)
    return (x, y)

for i in range(365):
    ts, td = add_seconds(datetime(2011, 4, 25), i*60**2*24)  # add i days via seconds
    if ts-td:  # test for difference in timestamp vs timedelta methods
        print(i, ts, td)
        break

Результат:

189 2011-10-30 23:00:00 2011-10-31 00:00:00

Как видите, существует расхождение именно30 октябряЭто для многих стран , вторая дата в году, когда мы видим корректировку перехода на летнее время.

Обновление: Аналогичный вопрос задается здесь: Разница между оценкой метки времени и итоговых_секунд .Основная причина разницы заключается в том, что datetime.timedelta не учитывает DST, в то время как timestamp учитывает это.

0 голосов
/ 14 мая 2018

Скорее всего, это связано с проблемой часового пояса. Я подозреваю, что при преобразовании в метку времени и обратно в дату и время информация о часовом поясе теряется.

...