У меня есть dt = datetime(2013,9,1,11)
, и я хотел бы получить метку времени Unix этого объекта datetime.
Когда я это сделаю, (dt - datetime(1970,1,1)).total_seconds()
я получу метку времени 1378033200
.
При конвертации обратно с помощью datetime.fromtimestamp
я получил datetime.datetime(2013, 9, 1, 6, 0)
.
Час не совпадает. Что я здесь пропустил?
timestamp
метод вместо того, чтобы пытаться сделать это самостоятельно. С одной стороны, это полностью исключает возможность вычитания наивных времен из разных часовых поясов.dt
берутся? Это местное время или время в UTC?Ответы:
То, что вы пропустили здесь, это часовые пояса.
Предположительно у вас пять часов свободного времени по UTC, поэтому 2013-09-01T11: 00: 00 по местному времени и 2013-09-01T06: 00: 00Z - это одно и то же время.
Вы должны прочитать верхнюю часть
datetime
документации, которая объясняет часовые пояса и "наивные" и "осведомленные" объекты.Если ваша первоначальная наивная дата-время была в формате UTC,
utcfromtimestamp
вместо нее можно использовать способ восстановленияfromtimestamp
.С другой стороны, если ваша первоначальная наивная дата-время была локальной, вы не должны были сначала вычесть из нее метку времени UTC; используйте
datetime.fromtimestamp(0)
вместо этого.Или, если у вас был осведомленный объект datetime, вам нужно либо использовать локальную (осведомленную) эпоху с обеих сторон, либо явно конвертировать в и из UTC.
Если у вас есть Python 3.3 или более поздней версии или вы можете обновить его, вы можете избежать всех этих проблем, просто используя
timestamp
метод, а не пытаясь понять, как это сделать самостоятельно. И даже если вы этого не сделаете, вы можете рассмотреть возможность заимствования его исходного кода .(И если вы можете подождать Python 3.4, похоже, что PEP 341 , вероятно, войдет в финальную версию, а это означает, что все то, о чем мы с Дж. Ф. Себастьяном говорили в комментариях, должно быть выполнимо только с помощью stdlib, и работает одинаково на Unix и Windows.)
источник
dt
используется местный часовой пояс, тоdatetime.fromtimestamp(0)
вместо этого следует использовать формулу в вопросе (эпоха в текущем часовом поясе)datetime(1970, 1,1)
(эпоха unix в UTC).fromtimestamp(0)
может произойти сбой, если система не хранит историческую информацию о часовом поясе, например, в Windows.pytz
может быть использован в этом случае.pytz
это не поможет, если вы уже не знаете, в каком часовом поясе вы находитесь; чтобы сделать это программно, вам нужна другая библиотека, которая получает текущий часовой пояс Windows и преобразует его вpytz
часовой пояс и / или ищет по имени.tzlocal
модуль, который также работает на Windows. Вот как вы можете конвертировать время UTC в местное время .решение
источник
d
это наивный объект даты / даты и времени, представляющий местное время (он может дать сбой в течение неоднозначных или прошлых / будущих дат, если ОС не предоставляет исторический tz db (смещение UTC в прошлом могло быть другим в локальном часовой пояс)). Больше вариантов .Если вы хотите преобразовать дату и время Python в секунды, начиная с эпохи, вы должны сделать это явно:
В Python 3.3+ вы можете использовать
timestamp()
вместо:источник
%s
, так как он будет привязан к часам системы, в которой вы сейчас находитесь. Вы должны только когда-либо использовать,.timestamp()
чтобы получить правильное время Epoch / UNIX.%s
не работает в системах Windows (ValueError: Invalid format string
)8
или9
Вместо этого выражения для создания метки времени POSIX
dt
,Использовать это:
Я получаю правильный ответ в вашем примере, используя второй метод.
РЕДАКТИРОВАТЬ: Некоторое продолжение ... После некоторых комментариев (см. Ниже), мне было любопытно по поводу отсутствия поддержки или документации для
%s
вstrftime
. Вот что я нашел:В исходном коде Python для
datetime
иtime
, строкаSTRFTIME_FORMAT_CODES
говорит нам:Так что теперь, если мы
man strftime
(в системах BSD, таких как Mac OS X), вы найдете поддержку для%s
:В любом случае, именно поэтому
%s
работает на системах, которые это делает. Но есть и более эффективные решения проблемы ОП (с учетом часовых поясов). Смотрите принятый ответ @ abarnert здесь.источник
strftime("%s")
в документации, я только что подтвердил это для работы на Mac и Linux. Спасибо.time.strftime()
иdatetime.strftime
документация делегируют платформамstrftime(3)
функцию для неподдерживаемых директив.%s
может произойти сбой даже в Mac OS X, например, datetime.strftime ('% s') должен учитывать tzinfo .%s
поскольку вы будете использовать только локализованное системное время системы, в которой вы находитесь. Вы хотите использовать,.timestamp()
если вы пытаетесь получить реальную метку времени UNIX.Для работы с часовыми поясами UTC:
источник
Вы пропустили информацию о часовом поясе (уже ответили, согласились)
arrow
упаковка позволяет избежать этой пытки с указанием даты; Он уже написан, протестирован, опубликован на pypi, кросс-Python (2.6 - 3.xx).Все что вам нужно:
pip install arrow
(или добавить в зависимости)Решение для вашего случая
источник
Если ваш объект datetime представляет время UTC, не используйте time.mktime, так как предполагается, что кортеж находится в вашем местном часовом поясе. Вместо этого используйте calendar.timegm:
источник
Что ж, при преобразовании метки времени в unix python обычно использует UTC, но при обратном преобразовании вы получите дату, конвертированную в местный часовой пояс.
Смотрите этот вопрос / ответ; Получить часовой пояс, используемый datetime.datetime.fromtimestamp ()
источник
Если вам нужна метка времени UTC:
time.mktime
только для локального dt. Использованиеcalendar.timegm
безопасно, но dt должна быть зоной utc, поэтому измените зону на utc. Если DT в UTC, просто используйтеcalendar.timegm
.источник
источник
Этот класс покрывает ваши потребности, вы можете передать переменную в ConvertUnixToDatetime и вызвать функцию, для которой вы хотите, чтобы она работала на основе.
источник