Как получить метку времени в UTC в Python - PullRequest
0 голосов
/ 10 января 2019

Я использую API с конечной точкой, которую можно фильтровать по дате. Дата должна быть в метке времени в секундах с начала эпохи, и она должна быть в UTC, чтобы API можно было правильно фильтровать

Это то, что я пробовал сегодня

first_day = datetime.utcnow().replace(day=1)
first_day = first_day.replace(hour=0, minute=0, second=0, microsecond=0)
print(first_day, int(first_day.timestamp()))

last_day =    datetime.utcnow().replace(day=calendar.monthrange(datetime.utcnow().year,     datetime.utcnow().month)[1])
last_day = last_day.replace(hour=0, minute=0, second=0, microsecond=0)
print(last_day, int(last_day.timestamp()))

Это мой вывод

2019-01-01 00:00:00 1546318800
2019-01-31 00:00:00 1548910800

А потом, когда я беру полученную временную метку 1546318800 в первый день января, а затем перехожу к https://www.epochconverter.com/ и вставляю ее в человеческую дату, я получаю следующее:

GMT: вторник, 1 января 2019 г., 5:00:00 Ваш часовой пояс: вторник, 1 января 2019 года, 12:00:00, GMT-05: 00

Я хочу, чтобы время по Гринвичу было 1 января 2019 года в 12:00:00

Как мне это сделать?

1 Ответ

0 голосов
/ 10 января 2019

Вы работаете с наивными datetime объектами. Для наивного datetime объекта предполагается, что время находится в местном времени, и поэтому сначала применяется смещение часового пояса вашей локальной системы. Из документации `datetime.timestamp () :

Предполагается, что

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

и далее:

Примечание : Нет способа получить метку времени POSIX непосредственно из наивного datetime экземпляра, представляющего время UTC. Если ваше приложение использует это соглашение и системный часовой пояс не установлен на UTC, вы можете получить временную метку POSIX, указав tzinfo=timezone.utc:

timestamp = dt.replace(tzinfo=timezone.utc).timestamp()

Обратите внимание, что вы можете значительно упростить логику вычисления даты, работая с daetime.date объектами и используя datetime.combine(); этот метод также принимает новое значение часового пояса, поэтому на данном этапе вы можете передать часовой пояс timezone.utc:

from datetime import datetime, date, time, timedelta, timezone

# create first and last day of the month
first_day = date.today().replace(day=1)
last_day = (first_day + timedelta(days=31)).replace(day=1) - timedelta(days=1)
first_day = int(datetime.combine(first_day, time.min, tzinfo=timezone.utc).timestamp())
last_day = int(datetime.combine(last_day, time.min, tzinfo=timezone.utc).timestamp())

Выше рассчитывается последний день месяца, сначала добавляя 31 день (гарантированно достигнув следующего месяца независимо от текущего), затем сбрасывая эту новую дату до первого дня месяца и затем вычитая один день.

Демо-версия:

>>> from datetime import datetime, date, time, timedelta, timezone
>>> first_day = date.today().replace(day=1)
>>> last_day = (first_day + timedelta(days=31)).replace(day=1) - timedelta(days=1)
>>> first_day, last_day
(datetime.date(2019, 1, 1), datetime.date(2019, 1, 31))
>>> int(datetime.combine(first_day, time.min, tzinfo=timezone.utc).timestamp())
1546300800
>>> int(datetime.combine(last_day, time.min, tzinfo=timezone.utc).timestamp())
1548892800

Обратите внимание, что полночь 31 января оставляет еще 24 часа месяца непокрытыми. Возможно, вы захотите удалить вычитание - timedelta(days=1) из вычисления last_day, приведенного выше, чтобы переключиться на полночь 1 февраля (1548979200), или используйте time.max, чтобы сместить отметку времени в 23:23:59 (за 1 секунду до полуночи) в 31 (1548979199).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...