Python time.time () возвращает локальную или UTC метку времени?

562

time.time()Возвращает ли модуль времени Python системное время или время в UTC?

Саранш Мохапатра
источник
87
Временные метки не имеют часовых поясов. Они представляют количество секунд, начиная с эпохи. Эпоха - это особый момент времени, который не зависит от часового пояса.
JWG
2
@jwg: обычно используемые метки времени POSIX не учитывают високосные секунды, и поэтому они не являются «числом [истекших СИ] секунд с начала эпохи» (они близки).
JFS
7
Я не думаю, что это точное возражение @JFSebastian. Дополнительные секунды не являются «прошедшими секундами с начала эпохи». Это изменения во временных представлениях, записанных часами, которые не соответствуют истекшим секундам.
JWG
4
@JFSebastian Извините за путаницу. Дополнительные секунды не являются прошедшими секундами. Поэтому временные метки, которые представляют собой «количество прошедших секунд», не включают и не должны включать високосные секунды.
JWG
2
@ jwg неправильно. Вы не можете стереть физическое время. Временная метка POSIX не является количеством прошедших секунд SI. Вот пример: между «31 декабря 2016 года в 6:59:59 вечера» и «31 декабря 2016 года в 7:00:01 вечера» в Нью-Йорке прошло 3 секунды, но разница в соответствующих временных метках POSIX составляет всего 2 секунды ( вторая секунда не засчитывается).
JFS

Ответы:

781

time.time()Функция возвращает количество секунд с начала эпохи, в секундах. Обратите внимание, что «эпоха» определяется как начало 1 января 1970 года в UTC. Таким образом, эпоха определяется в терминах UTC и устанавливает глобальный момент времени. Независимо от того, где вы находитесь «секунды после эпохи» (time.time ()) возвращает одно и то же значение в один и тот же момент.

Вот пример выходных данных, которые я запустил на своем компьютере, также преобразовав их в строку.

Python 2.7.3 (default, Apr 24 2012, 00:00:54) 
[GCC 4.7.0 20120414 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> ts = time.time()
>>> print ts
1355563265.81
>>> import datetime
>>> st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
>>> print st
2012-12-15 01:21:05
>>>

tsПеременное время возвращается в секундах. Затем я преобразовал его в строку, используя datetimeбиблиотеку, сделав ее строкой, удобочитаемой для человека.

squiguy
источник
72
Почему мы должны, import timeкогда datetime в основном дает вам метку времени. Просто удалите миллисекунды -str(datetime.datetime.now()).split('.')[0]
Хуссейн
17
@Alexis Unix эпоха определяется здесь довольно четко . Это даже указывает на пример Python пути вниз по странице. Я не понимаю ваш комментарий.
squiguy
9
@ Честно говоря, я не помню, что заставило меня так говорить. Должно быть, я что-то неправильно понял, и я пытался выяснить, почему некоторые тесты ломались, когда я переехал между Францией и США, чтобы, наконец, выяснить, что проблема заключалась в летнем времени, которое продлевает неделю в этот период года. Извините за это и спасибо за указание на это.
Алексис
5
это не «секунды в UTC». , Возвращенная метка времени time.time()не находится ни в одном часовом поясе . «секунды с начала эпохи» - это термин; это не истекшие секунды с некоторого момента времени (эпоха). Вы можете легко преобразовать его в местное время (с базой данных tz) и / или часовой пояс UTC. Кстати, если вы отбрасываете .strftime()результат (почти) то же самое (+/- микросекунды).
JFS
3
только что проверил, time.time () не дает время UTC, оно дает время моей локальной зоны
sliders_alpha
302

Это для текстовой формы метки времени, которую можно использовать в ваших текстовых файлах. (В прошлом название вопроса было другим, поэтому введение в этот ответ было изменено, чтобы уточнить, как его можно интерпретировать как время. [Обновлено 2016-01-14])

Вы можете получить временную метку в виде строки , используя .now()или .utcnow()из datetime.datetime:

>>> import datetime
>>> print datetime.datetime.utcnow()
2012-12-15 10:14:51.898000

В nowотличается от , utcnowкак и ожидалось - в противном случае они работают точно так же:

>>> print datetime.datetime.now()
2012-12-15 11:15:09.205000

Вы можете визуализировать метку времени в строке явно:

>>> str(datetime.datetime.now())
'2012-12-15 11:15:24.984000'

Или вы можете даже более явно отформатировать временную метку так, как вам нравится:

>>> datetime.datetime.now().strftime("%A, %d. %B %Y %I:%M%p")
'Saturday, 15. December 2012 11:19AM'

Если вы хотите формат ISO, используйте .isoformat()метод объекта:

>>> datetime.datetime.now().isoformat()
'2013-11-18T08:18:31.809000'

Вы можете использовать их в переменных для расчетов и печати без преобразований.

>>> ts = datetime.datetime.now()
>>> tf = datetime.datetime.now()
>>> te = tf - ts
>>> print ts
2015-04-21 12:02:19.209915
>>> print tf
2015-04-21 12:02:30.449895
>>> print te
0:00:11.239980
pepr
источник
1
Я хотел время эпохи .... не в формате даты ... как было видно из моего упоминания о команде time.time ()
Саранш Мохапатра
34
Без проблем. Кому-то может понадобиться отметка времени для размещения в текстовых файлах.
pepr
1
Я еще один, перенаправленный сюда, вероятно, из-за необоснованного количества голосов. Вопрос неверен, и принятый ответ вводит в заблуждение типичную потребность: получить удобочитаемый суффикс - скажем, для имен файлов - в наиболее часто используемом часовом поясе сервера.
Чтобы распечатать временную метку как часть строки, используйте это: Python2: import datetime; print "%s: My timestamp message" % datetime.datetime.utcnow()Python3:import datetime; print ("%s: My timestamp message" % datetime.datetime.utcnow())
Mr-IDE
datetime.datetime.utcnow()это зло Это создает наивное время даты, которое не является местным временем. Если ваше местное время не UTC, оно будет НЕПРАВИЛЬНЫМ. Используйте datetime.datetime.now(datetime.timezone.utc)вместо этого. Это создает дату / время с учетом часового пояса, представляющее текущее время.
Террел
139

Основываясь на ответе из #squiguy, чтобы получить истинную временную метку, я набрал бы команду cast из float.

>>> import time
>>> ts = int(time.time())
>>> print(ts)
1389177318

По крайней мере, это концепция.

Руди Стридом
источник
1
Какова причина для типизации временной метки? Какой тип по умолчанию?
Тиззи
3
@Tizzee type(time.time())дает<type 'float'>
знаменитые Garkin
4
Но если вам нужно более точное время, чем в секундах, поплавок имеет смысл.
pepr
3
@RudiStrydom: Python строго типизирован. Не путайте это со статической типизацией.
JFS
1
@CheokYanCheng: int()полиморфный. При необходимости он возвращается longв старых версиях Python - все целые числа длинные в новых версиях Python.
JFS
30

Ответом может быть ни то, ни другое.

  • кроме того: time.time()возвращает примерно количество секунд, прошедших с начала эпохи. Результат не зависит от часового пояса, поэтому это не UTC или местное время. Вот определение POSIX для «Секунды с эпохи» .

  • и то и другое: time.time()не требует синхронизации часов вашей системы, поэтому она отражает их значение (хотя это не имеет никакого отношения к местному часовому поясу). Разные компьютеры могут получать разные результаты одновременно. С другой стороны , если ваш компьютер время будет синхронизирована , то легко получить UTC время от метки времени (если мы будем игнорировать високосные секунды):

    from datetime import datetime
    
    utc_dt = datetime.utcfromtimestamp(timestamp)

Информацию о том, как получить метки времени из времени UTC в различных версиях Python, см. В разделе Как получить дату, конвертированную в секунды с начала эпохи по UTC?

JFS
источник
4
Это единственный ответ, который правильно упоминается, в datetime.utcfromtimestampто время как есть 308 голосов за ответ datetime.fromtimestamp:-(
@TerrelShumway вопрос в том, что time.time()возвращает функция (она очень короткая). Ваш комментарий относится к другому вопросу (вы изменили свой комментарий, так как я начал отвечать на него. В худшую сторону). Примечание в стороне; Слово «правильно» следует использовать с осторожностью (часовые пояса сложны - там нет серебряной пули - только компромиссы для конкретного варианта использования).
JFS
Не используйте datetime.datetime.utcfromtimestamp(ts). Если ваше местное время не указано в формате UTC, оно будет НЕПРАВИЛЬНЫМ, поскольку оно создает наивную дату, а не местное время. Используйте datetime.datetime.fromtimestamp(ts,datetime.timezone.utc)вместо этого. Это создает дату и время с учетом часового пояса, представляющие тот же момент времени, что и отметка времени.
Террел
Да. Мой предыдущий комментарий был совершенно неверным. Большая часть кода в модуле datetime обрабатывает наивные datetime как местное время. Использование наивных datetime похоже на открытие текстового файла без знания кодировки.
Террел
@TerrelShumway Неправильно предполагать, что время UTC может использоваться только в системах, где это местное время. Это правда, что некоторые части stdlib рассматривают наивные объекты даты и времени как имеющие местный часовой пояс (к сожалению). Я бы предпочел, чтобы naive_dt.astimezone()он не существовал, как неявный, bytes.encode()более не существует в Python 3. Это правда, что во многих случаях полезно работать с временем UTC внутри. О модуле datetime можно сказать очень много (я ответил на достаточно много вопросов, чтобы получить золотой значок), большинство из них выходит за рамки вопроса: что time.time()возвращает.
JFS
4

В конце концов я согласился на:

>>> import time
>>> time.mktime(time.gmtime())
1509467455.0
Natim
источник
1
Это может удовлетворить ваши местные потребности, но может ввести в заблуждение людей, которые ожидают, что числа в этом диапазоне будут секундами с эпохи [GMT]. time.time()возвращает десятичное число / число с плавающей запятой, 1574115250.818733и миллисекунды, так как эпоха легко, int(time.time() * 1000)например,1574115254915
MarkHu
3

В определенном часовом поясе нет такого понятия, как «эпоха». Эпоха четко определена как определенный момент времени, поэтому, если вы измените часовой пояс, само время также изменится. Именно на этот раз Jan 1 1970 00:00:00 UTC. Так time.time()возвращает количество секунд с начала эпохи.

HyperNeutrino
источник
Хотя верно то, что UTC является стандартом времени, а не часовым поясом, стандартом является то, что оно делит то же время, что и время по Гринвичу. Итак ...
Крейг Хикс
3

timestamp - это всегда время в utc, но при вызове datetime.datetime.fromtimestamp оно возвращает время в вашем местном часовом поясе, соответствующее этой отметке времени, поэтому результат зависит от вашей локали.

>>> import time, datetime

>>> time.time()
1564494136.0434234

>>> datetime.datetime.now()
datetime.datetime(2019, 7, 30, 16, 42, 3, 899179)
>>> datetime.datetime.fromtimestamp(time.time())
datetime.datetime(2019, 7, 30, 16, 43, 12, 4610)

Там есть хорошая библиотека arrowс другим поведением. В том же случае он возвращает вам объект времени с часовым поясом UTC.

>>> import arrow
>>> arrow.now()
<Arrow [2019-07-30T16:43:27.868760+03:00]>
>>> arrow.get(time.time())
<Arrow [2019-07-30T13:43:56.565342+00:00]>
Рябченко Александр
источник