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.

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.


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


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


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'

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'

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'

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

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]

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]

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'
>>> 

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))

Znakomity. Prosty, elastyczny i niezależny od platformy (w przeciwieństwie do strftime).
Endre Both
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.