Python datetime в строку без микросекундного компонента


410

Я добавляю строки времени UTC к ответам Bitbucket API, которые в настоящее время содержат только строки времени Амстердама (!). Для согласованности с временными строками UTC, возвращенными в другом месте, желаемый формат 2011-11-03 11:07:04(с последующим+00:00 , но это не уместно).

Каков наилучший способ создания такой строки ( без микросекундного компонента) из datetimeэкземпляра с микросекундным компонентом?

>>> import datetime
>>> print unicode(datetime.datetime.now())
2011-11-03 11:13:39.278026

Я добавлю лучший вариант, который мне пришёл в голову, в качестве возможного ответа, но вполне может быть более элегантное решение.

Изменить: я должен отметить, что я на самом деле не печатаю текущее время - я использовал datetime.nowдля быстрого примера. Таким образом, решение не должно предполагать, что любые datetimeполученные экземпляры будут включать микросекундные компоненты.

Ответы:


840

Если вы хотите отформатировать datetimeобъект в определенном формате, который отличается от стандартного формата, лучше явно указать этот формат:

>>> datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
'2011-11-03 18:21:26'

См. Документациюdatetime.strftime() для объяснения %директив.


10
Коллега только что убедительно доказал, что это правильный подход. Считай меня убежденным.
Дэвид Чамберс

3
Что это был за убедительный случай - поставить это решение над вашим решением, используя datetime.replace?
matlehmann

13
@matlehmann: Конечно, я не знаю аргументов коллеги Дэвидхемберса. Тем не менее, я думаю, что если вы хотите напечатать дату в очень специфическом формате, вы должны четко указать это намерение. Код в этом ответе гласит: «возьмите текущее время и отформатируйте его в точности так». Код в другом ответе говорит: «возьмите текущее время, установите микросекунды равными 0, а затем каким-то образом преобразуйте его в строку».
Свен Марнач

3
+1, явное понимание формата строки позволяет избежать проблем, если стандартное преобразование datetime-str изменится в будущей версии Python
Alan Evangelista

2
@DylanYoung Требование OP состоит в том, чтобы напечатать объект datetime в формате, отличном от стандартного возвращаемого формата .isoformat(), который по умолчанию включает микросекунды. Если это то, что вам нужно, проясните это. Каждый сразу поймет, что делает этот код. Вряд ли кто-то поймет другой код, не взглянув на документацию.
Свен Марнах

172
>>> import datetime
>>> now = datetime.datetime.now()
>>> print unicode(now.replace(microsecond=0))
2011-11-03 11:19:07

20
Я думаю, что это правильное решение, потому что оно читаемо, задокументировано и соответствует поведению: « .isoformat([sep])- Вернуть строку, представляющую дату и время в формате ISO 8601, ГГГГ-ММ-ДДТЧ: ММ: СС.мммммм или, если микросекунда равна 0, ГГГГ-ММ-ДДЧЧ: ММ: СС "
Bengt

1
в моей ситуации дата уже была построена, и мне нужно было «напечатать» ее до второй. это прекрасно, спасибо.
Вигронд

1
Это лучший ответ!
Havok

Гораздо лучше, чем форматирование или разбор строк для сравнения, спасибо.
Зак Янг

69

В Python 3.6:

from datetime import datetime
datetime.datetime.now().isoformat(' ', 'seconds')
'2017-01-11 14:41:33'

https://docs.python.org/3.6/library/datetime.html#datetime.datetime.isoformat


4
Я думаю, что сейчас, спустя 8 лет с появлением Python 3.6, это должен быть общепринятый ответ. Это дает лучшие из обоих миров поспорили о по @DylanYoung и AlexanderMP по этой же теме здесь
pfabri


47

Это способ, которым я делаю это. Формат ISO:

import datetime
datetime.datetime.now().replace(microsecond=0).isoformat()
# Returns: '2017-01-23T14:58:07'

Вы можете заменить 'T', если вы не хотите формат ISO:

datetime.datetime.now().replace(microsecond=0).isoformat(' ')
# Returns: '2017-01-23 15:05:27'

Это похоже на мой ответ. Есть ли причина в пользу .isoformat()более unicode()?
Дэвид Чамберс

1
Зависит от того, что вы хотите, если вы хотите использовать представление строки Python unicode(), и если вы хотите ISO-8601, используйтеisoformat()
Radtek

Понимаю. unicode()удобнее чем .isoformat().replace('T', ' '), конечно. ;)
Дэвид Чамберс

Я бы просто использовал решение Свена для формата, отличного от iso, оно более явное: datetime.now (). Strftime ("% Y-% m-% d% H:% M"), но замена 'T' это просто еще один путь. Может быть лучшим решением, если вам нужны даты ISO и Unicode.
Радтек

isoformatпринимает спецификатор разделителя, поэтому замена не должна производиться. просто сделать:datetime.datetime.now().replace(microsecond=0).isoformat(' ')
Койя

17

Еще один вариант:

>>> import time
>>> time.strftime("%Y-%m-%d %H:%M:%S")
'2011-11-03 11:31:28'

По умолчанию здесь используется местное время, если вам нужно UTC, вы можете использовать следующее:

>>> time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
'2011-11-03 18:32:20'

Даунвот, потому что ОП спрашивал о дате, а не о времени.
Юрген А. Эрхард

15

Оставьте первые 19 символов, которые вы хотели с помощью нарезки:

>>> str(datetime.datetime.now())[:19]
'2011-11-03 14:37:50'

5
Это неверно только потому, что к временным строкам может быть добавлена ​​спецификация часового пояса, например +05:30. Правильно было бы str(now())[:19].
K3 --- rnc

1
@ K3 --- rnc: Спасибо. Обновлено в соответствии с вашим предложением.
Стивен Румбальски

через год 10000будет пропущена
секунда

время покажет @diti;)
yǝsʞǝla

8

Я обычно делаю:

import datetime
now = datetime.datetime.now()
now = now.replace(microsecond=0)  # To print now without microsecond.

# To print now:
print(now)

вывод:

2019-01-13 14:40:28

7

Поскольку не во всех datetime.datetimeэкземплярах есть микросекундный компонент (т. Е. Когда он равен нулю), вы можете разбить строку на «.» и возьмите только первый элемент, который всегда будет работать:

unicode(datetime.datetime.now()).partition('.')[0]

3

Мы можем попробовать что-то вроде ниже

import datetime

date_generated = datetime.datetime.now()
date_generated.replace(microsecond=0).isoformat(' ').partition('+')[0]

Это хуже .isoformat(' ', 'seconds'), чем предложено в предыдущем ответе.
Дэвид Чэмберс

1
Когда я пытаюсь предложить предложенный ранее ответ выше, я получаю сообщение об ошибке ниже >>> datetime.datetime.now (). Isoformat ('', 'seconds') Traceback (последний вызов был последним): файл "<stdin>", строка 1, в <module> TypeError: isoformat () принимает не более 1 аргумента (2 дано)
Abhishek Bajaj,

Ах я вижу. Это работает для меня в Python 3, но не в Python 2.
Davidchambers

Я использую версию Python 3.4.3, в которой я вижу эту ошибку. >>> datetime.datetime.now (). isoformat ('', 'seconds') Traceback (последний вызов был последним): файл "<stdin>", строка 1 в <module> TypeError: isoformat () занимает не более 1 аргумент (2 дано)
Абхишек Баджай

1

Я нашел это самым простым способом.

>>> t = datetime.datetime.now()
>>> t
datetime.datetime(2018, 11, 30, 17, 21, 26, 606191)
>>> t = str(t).split('.')
>>> t
['2018-11-30 17:21:26', '606191']
>>> t = t[0]
>>> t
'2018-11-30 17:21:26'
>>> 

datetime.datetime.now (). strftime ("% Y-% m-% d% H:% M:% S") '2011-11-03 18:21:26' намного проще, imo. Но легко не всегда лучший
An0n

1

Я использую это, потому что я могу понять и, следовательно, лучше помнить это (и формат даты и времени также может быть настроен на основе вашего выбора): -

import datetime
moment = datetime.datetime.now()
print("{}/{}/{} {}:{}:{}".format(moment.day, moment.month, moment.year,
                                 moment.hour, moment.minute, moment.second))

Brilliant. Простой, гибкий и независимый от платформы (в отличие от strftime).
Endre Both
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.