Python datetime do ciągu bez mikrosekundowego komponentu

410

Dodam ciągi czasu UTC do odpowiedzi API Bitbucket, które obecnie zawierają tylko ciągi czasu Amsterdam (!). Aby zachować spójność z ciągami czasowymi UTC zwracanymi w innym miejscu, pożądanym formatem jest 2011-11-03 11:07:04(po którym następuje +00:00, ale to nie jest istotne).

Jaki jest najlepszy sposób na utworzenie takiego ciągu ( bez składnika mikrosekundowego) z datetimeinstancji ze składnikiem mikrosekundowym?

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

Jako najlepszą odpowiedź dodam najlepszą możliwą opcję, ale może istnieć bardziej eleganckie rozwiązanie.

Edycja: Powinienem wspomnieć, że tak naprawdę nie drukuję aktualnego czasu - datetime.nowpodałem szybki przykład. Dlatego rozwiązanie nie powinno zakładać, że wszelkie datetimeotrzymywane instancje będą zawierać elementy mikrosekundowe.

davidchambers
źródło

Odpowiedzi:

840

Jeśli chcesz sformatować datetimeobiekt w określonym formacie innym niż standardowy, najlepiej wyraźnie określić ten format:

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

Zobacz dokumentacjędatetime.strftime() o wyjaśnienie tych %dyrektyw.

Sven Marnach
źródło
10
Kolega właśnie przedstawił przekonujący argument za tym, że jest to właściwe podejście. Uważaj mnie za przekonanego.
davidchambers
3
Co to za przekonujący przypadek - umieszczenie tego rozwiązania nad rozwiązaniem za pomocą datetime.replace?
matlehmann
13
@matlehmann: Oczywiście nie znam argumentów kolegi Davidchambersa. Myślę jednak, że jeśli zamierzasz wydrukować datę w bardzo konkretnym formacie, powinieneś wyraźnie powiedzieć o tym zamiarze. Kod w tej odpowiedzi mówi „nie bierz aktualnego czasu i sformatuj go dokładnie w ten sposób”. Kod w drugiej odpowiedzi mówi „nie bierz aktualnego czasu, ustaw mikrosekundy na 0, a następnie przekonwertuj go na ciąg znaków”.
Sven Marnach
3
+1, jasne wyrażanie się na temat formatu ciągu pozwala uniknąć problemów, jeśli standardowa konwersja datetime-str zmieni się w przyszłej wersji Pythona
Alan Evangelista
2
@DylanYoung Wymaganiem PO jest wydrukowanie obiektu daty / godziny w formacie innym niż standardowy format zwracany przez .isoformat(), który domyślnie zawiera mikrosekundy. Jeśli tego potrzebujesz, wyrażaj się jasno. Wszyscy natychmiast zrozumieją, co robi ten kod. Prawie nikt nie zrozumie drugiego kodu bez przeglądania dokumentacji.
Sven Marnach,
172
>>> import datetime
>>> now = datetime.datetime.now()
>>> print unicode(now.replace(microsecond=0))
2011-11-03 11:19:07
davidchambers
źródło
1
w mojej sytuacji data została już skonstruowana i musiałem ją „posadzić” do drugiej. to jest idealne, dzięki.
Vigrond,
1
To najlepsza odpowiedź!
Havok
Znacznie lepiej niż formatowanie lub parsowanie ciągów dla porównania, dziękuję.
Zach Young
69

W 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

codeif
źródło
4
Myślę, że teraz, 8 lat później, wraz z pojawieniem się Pythona 3.6, powinna to być powszechnie przyjęta odpowiedź. To oferuje lepsze z obu światów, o które argumentowali @DylanYoung i AlexanderMP w tym samym wątku tutaj
pfabri
47

Tak to robię. Format ISO:

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

Możesz zastąpić „T”, jeśli nie chcesz formatu ISO:

datetime.datetime.now().replace(microsecond=0).isoformat(' ')
# Returns: '2017-01-23 15:05:27'
radtek
źródło
To jest podobne do mojej odpowiedzi. Czy istnieje powód, aby faworyzować .isoformat()nad unicode()?
davidchambers
1
Zależy, co chcesz, jeśli chcesz użyć reprezentacji ciągu python unicode(), a jeśli chcesz ISO-8601, użyjisoformat()
radtek
Widzę. unicode()jest wygodniejszy niż na .isoformat().replace('T', ' ')pewno. ;)
davidchambers
Po prostu użyłbym rozwiązania Svena dla formatu nie-ISO, jego bardziej wyraźny: datetime.now (). Strftime („% Y-% m-% d% H:% M”), ale zastąpienie „T” jest tylko kolejnym droga. Może być najlepszym rozwiązaniem, jeśli potrzebujesz zarówno daty ISO, jak i Unicode.
radtek
isoformatakceptuje specyfikator separatora, więc nie należy go zastępować. po prostu zrób:datetime.datetime.now().replace(microsecond=0).isoformat(' ')
coya
17

Jeszcze inna opcja:

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

Domyślnie wykorzystuje to czas lokalny, jeśli potrzebujesz UTC, możesz użyć następujących opcji:

>>> time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
'2011-11-03 18:32:20'
Andrew Clark
źródło
Oddaj głos, ponieważ OP zapytał o datę, a nie czas.
Jürgen A. Erhard
15

Zachowaj pierwszych 19 znaków, które chciałeś wyciąć:

>>> str(datetime.datetime.now())[:19]
'2011-11-03 14:37:50'
Steven Rumbalski
źródło
5
Jest to niepoprawne, ponieważ do ciągów czasowych można dołączyć specyfikację strefy czasowej, np +05:30. Prawidłowe byłoby str(now())[:19].
K3 --- rnc
1
@ K3 --- rnc: Dzięki. Zaktualizowano zgodnie z twoją sugestią.
Steven Rumbalski
po roku 10000sekunda zostanie pominięta
diti
czas pokaże @diti;)
28sʞǝla
8

Zwyklę robię:

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

# To print now:
print(now)

wynik:

2019-01-13 14:40:28
An0n
źródło
7

Ponieważ nie wszystkie datetime.datetimeinstancje mają składnik mikrosekundowy (tzn. Gdy jest równy zero), możesz podzielić ciąg na „.” i weź tylko pierwszy przedmiot, który zawsze zadziała:

unicode(datetime.datetime.now()).partition('.')[0]
Austin Marshall
źródło
3

Możemy spróbować czegoś takiego jak poniżej

import datetime

date_generated = datetime.datetime.now()
date_generated.replace(microsecond=0).isoformat(' ').partition('+')[0]
Abhishek Bajaj
źródło
Jest to gorsze niż .isoformat(' ', 'seconds')zaproponowane we wcześniejszej odpowiedzi.
davidchambers
1
Kiedy próbuję powyżej proponowanej wcześniejszej odpowiedzi, dochodzę do błędu >>> datetime.datetime.now (). Isoformat ('', 'seconds') Traceback (ostatnie ostatnie wywołanie): Plik "<stdin>", wiersz 1, w <module> TypeError: isoformat () przyjmuje najwyżej 1 argument (2 podane)
Abhishek Bajaj
O, rozumiem. Działa dla mnie w Pythonie 3, ale nie w Pythonie 2.
davidchambers
Używam wersji Python 3.4.3, ponieważ widzę ten błąd. >>> datetime.datetime.now (). isoformat ('', 'seconds') Traceback (ostatnie ostatnie wywołanie): Plik „<stdin>”, wiersz 1, w <module> TypeError: isoformat () zajmuje najwyżej 1 argument (2 podane)
Abhishek Bajaj
1

Uważam, że jest to najprostszy sposób.

>>> 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'
>>> 
Muhammed Irfan
źródło
datetime.datetime.now (). strftime ("% Y-% m-% d% H:% M:% S") '2011-11-03 18:21:26' dużo łatwiej imo. Ale łatwość nie jest zawsze najlepsza
An0n
1

Korzystam z tego, ponieważ mogę go lepiej zrozumieć i dlatego lepiej go zapamiętać (a format daty i godziny można również dostosować w zależności od wyboru): -

import datetime
moment = datetime.datetime.now()
print("{}/{}/{} {}:{}:{}".format(moment.day, moment.month, moment.year,
                                 moment.hour, moment.minute, moment.second))
satyakam shashwat
źródło
Znakomity. Prosty, elastyczny i niezależny od platformy (w przeciwieństwie do strftime).
Endre Both