Как получить время UTC в Python?

112

Я много раз искал решение на StackExchange, но ничего не помогло. В JavaScript я использую следующее для расчета времени UTC с 1 января 1970 года:

function UtcNow() {
    var now = new Date();
    var utc = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds(), now.getUTCMilliseconds());
    return utc;
}

Каким был бы эквивалентный код Python?

Джеймс Кларк
источник
Подождите, вы используете Python или JavaScript?
CheetSheatOverlode

Ответы:

179

Попробуйте этот код, который использует datetime.utcnow () :

from datetime import datetime
datetime.utcnow()

Для ваших целей, когда вам нужно рассчитать количество времени, потраченного между двумя датами, все, что вам нужно, это вычесть даты окончания и начала. Результатом такого вычитания является объект timedelta.

Из документов python:

class datetime.timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])

А это означает, что по умолчанию вы можете получить любое из полей, упомянутых в его определении - дни, секунды, микросекунды, миллисекунды, минуты, часы, недели. Также экземпляр timedelta имеет метод total_seconds (), который:

Возвращает общее количество секунд, содержащихся в продолжительности. Эквивалентно (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 * 6) / 10 * 6, вычисляемому с включенным истинным делением.

Артем Рудзенко
источник
2
возможно, неприятный сюрприз по поводу datetime.utcnow () заключается в том, что он не возвращает объект с учетом часового пояса, несмотря на имя. На мой взгляд, это большая проблема, поэтому я предпочитаю свой ответ ниже. См. «Объекты datetime без часового пояса следует рассматривать как« ошибку »в приложении». julien.danjou.info/python-and-timezones
Тим Ричардсон
1
Концепция так называемого наивного объекта datetime (т.е. не задана информация о часовом поясе) действительно служит цели: я хочу, чтобы мой будильник звонил в 06:00:00 каждый день, независимо от того, где я нахожусь. Также он позволяет использовать «виртуальные часы», скажем, в компьютерных играх: в моем мире фантазий сейчас 5 часов вечера. Принуждение часового пояса к объекту datetime было бы неудобным, особенно с арифметикой timedelta.
DustByte
42

В форме, наиболее близкой к вашему оригиналу:

import datetime

def UtcNow():
    now = datetime.datetime.utcnow()
    return now

Если вам нужно знать количество секунд с 1970-01-01, а не на родном Python datetime, используйте вместо этого:

return (now - datetime.datetime(1970, 1, 1)).total_seconds()

У Python есть соглашения об именах, которые расходятся с тем, к чему вы, возможно, привыкли в Javascript, см. PEP 8 . Кроме того, функция, которая просто возвращает результат другой функции, довольно глупа; если нужно просто сделать его более доступным, вы можете создать другое имя для функции, просто назначив его. Первый пример выше можно заменить на:

utc_now = datetime.datetime.utcnow
Марк Рэнсом
источник
1
Мне ваш ответ нравится больше, чем тот, который получил более высокую оценку сверху. Спасибо за глубину здесь.
Jordan Dea-Mattson
@Jordan, оглядываясь назад на мой ответ, я понимаю, что сделал стилистическую ошибку, поместив импорт внутри функции, а не на глобальном уровне, я собираюсь исправить это сейчас.
Марк Рэнсом
8
Возможно, вам стоит подумать о переносе UtcNow () в другую функцию. Это слишком просто. Также не используйте подчеркивания. PEP 8 такой скучный ...
vcarel
1
Определенно не нужно писать функцию, возвращающую простой однострочный ... datetime.datetime.utcnow ()
cpreid
1
@TimRichardson Я не возражаю, но на момент написания этого ответа альтернативы не было - Python не включал никаких tzinfoобъектов даже для UTC.
Марк Рэнсом
32

Только простая стандартная библиотека для современного Python. Предоставляет дату и время с учетом часового пояса, в отличие от datetime.utcnow(). datetimesбез часовых поясов ждут аварии.

from datetime import datetime,timezone
now_utc = datetime.now(timezone.utc)
Тим Ричардсон
источник
5
Согласно документации Python 3, это рекомендуемый способ сделать это.
roskakori 04
Чисто и просто! Должен быть предпочтительным способом.
Marry35
21
import datetime
import pytz

# datetime object with timezone awareness:
datetime.datetime.now(tz=pytz.utc)

# seconds from epoch:
datetime.datetime.now(tz=pytz.utc).timestamp() 

# ms from epoch:
int(datetime.datetime.now(tz=pytz.utc).timestamp() * 1000) 
MikeL
источник
10

Начиная с datetime.datetime вы уже можете экспортировать в метки времени с помощью метода strftime. Следуя вашему примеру функции:

import datetime
def UtcNow():
    now = datetime.datetime.utcnow()
    return int(now.strftime("%s"))

Если вам нужны микросекунды, вам нужно изменить строку экспорта и привести ее к float, например: return float(now.strftime("%s.%f"))

Гекторканто
источник
В чем смысл преобразования в строку, а затем обратно в число, если вы можете получить число напрямую?
Марк Рэнсом
Дело в том, что вы можете захотеть изменить что-то в функции, и по этой причине лучше придерживаться объекта datetime, а не использовать. time.time()Вы также можете использовать time.mktime (now.timetuple ()) для преобразования непосредственно в int. Во всяком случае, для этого простого случая time.time()тоже допустимый вариант. Что мне показалось странным, так это то, что timedelta ищет секунды.
hectorcanto
Обратите внимание, что strftime("%s")это зависит от платформы и не работает в Windows. (По крайней мере, для меня это не так в Windows 10).
Джулиан Кирш
8

Информация о часовом поясе с нулевыми внешними зависимостями:

from datetime import datetime, timezone

def utc_now():
    return datetime.utcnow().replace(tzinfo=timezone.utc)
Сезар Канасса
источник
-4

В Python 3 с использованием лямбда-выражения попробуйте;

from datetime import datetime
utc_now = lambda : datetime.utcnow()

и вызвать функцию в обычном режиме;

print(utc_now())
УЛИЦА ДЕНЬГИ
источник
2
Будьте милы, ребята; ^)
Демис