Python datetime a cadena sin componente microsegundo

410

Estoy agregando cadenas de tiempo UTC a las respuestas de API de Bitbucket que actualmente solo contienen cadenas de tiempo de Amsterdam (!). Para mantener la coherencia con las cadenas de tiempo UTC devueltas en otro lugar, el formato deseado es 2011-11-03 11:07:04(seguido de+00:00 , pero no es pertinente).

¿Cuál es la mejor manera de crear una cadena de este tipo ( sin un componente de microsegundos) a partir de una datetimeinstancia con un componente de microsegundos?

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

Agregaré la mejor opción que se me haya ocurrido como una posible respuesta, pero puede haber una solución más elegante.

Editar: debo mencionar que en realidad no estoy imprimiendo la hora actual; solía datetime.nowproporcionar un ejemplo rápido. Por lo tanto, la solución no debe suponer que cualquier datetimeinstancia que reciba incluirá componentes de microsegundos.

davidchambers
fuente

Respuestas:

840

Si desea formatear un datetimeobjeto en un formato específico que es diferente del formato estándar, es mejor especificar explícitamente ese formato:

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

Consulte la documentación dedatetime.strftime() para obtener una explicación de las %directivas.

Sven Marnach
fuente
10
Un colega acaba de presentar un argumento convincente para que este sea el enfoque correcto. Considérame convencido.
davidchambers 03 de
3
¿Cuál fue ese caso convincente: poner esta solución por encima de su solución usando datetime.replace?
matlehmann
13
@matlehmann: Por supuesto, no conozco los argumentos del colega de davidchambers. Sin embargo, creo que si su intención es imprimir una fecha en un formato muy específico, debe ser explícito sobre esta intención. El código en esta respuesta dice "toma la hora actual y formatea exactamente como esta". El código en la otra respuesta dice "toma el tiempo actual, establece los microsegundos en 0 y luego conviértelo en una cadena de alguna manera".
Sven Marnach
3
+1, ser explícito sobre el formato de cadena evita problemas si la conversión estándar de fecha y hora cambia en una futura versión de Python
Alan Evangelista
2
@DylanYoung El requisito del OP es imprimir un objeto de fecha y hora en un formato diferente del formato estándar devuelto por .isoformat(), que incluye los microsegundos de forma predeterminada. Si eso es lo que necesita, sea explícito al respecto. Todos entenderán de inmediato lo que hace este código. Casi nadie entenderá el otro código sin mirar la documentación.
Sven Marnach
172
>>> import datetime
>>> now = datetime.datetime.now()
>>> print unicode(now.replace(microsecond=0))
2011-11-03 11:19:07
davidchambers
fuente
1
en mi situación, la fecha ya se había construido y necesitaba "ponerla" a la segunda. Esto es perfecto, gracias.
Vigrond
1
¡Esta es la mejor respuesta!
Havok
Mucho mejor que formatear o analizar cadenas para la comparación, gracias.
Zach Young
47

Así es como lo hago. Formato ISO:

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

Puede reemplazar la 'T' si no desea el formato ISO:

datetime.datetime.now().replace(microsecond=0).isoformat(' ')
# Returns: '2017-01-23 15:05:27'
radtek
fuente
Esto es similar a mi respuesta. ¿Hay alguna razón para favorecer .isoformat()más unicode()?
davidchambers
1
Depende de lo que desee, si desea usar la representación de cadena de Python unicode(), y si desea ISO-8601, useisoformat()
radtek
Veo. unicode()Es más conveniente que .isoformat().replace('T', ' '), sin duda. ;)
davidchambers
Simplemente usaría la solución de Sven para el formato no iso, es más explícito: datetime.now (). Strftime ("% Y-% m-% d% H:% M"), pero reemplazar la 'T' es solo otra camino. Puede ser la mejor solución si necesita tanto ISO como fecha unicode.
radtek
isoformatacepta el separador especificador, por lo que no se debe reemplazar. acaba de hacer:datetime.datetime.now().replace(microsecond=0).isoformat(' ')
coya
17

Otra opción más:

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

Por defecto, esto usa la hora local, si necesita UTC puede usar lo siguiente:

>>> time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
'2011-11-03 18:32:20'
Andrew Clark
fuente
Voto negativo porque el OP preguntó por fecha y hora, no por hora.
Jürgen A. Erhard
15

Mantenga los primeros 19 caracteres que deseaba mediante el corte:

>>> str(datetime.datetime.now())[:19]
'2011-11-03 14:37:50'
Steven Rumbalski
fuente
55
Esto solo es incorrecto porque las cadenas de tiempo pueden tener especificación de zona horaria adjunta, por ejemplo +05:30. Correcto sería str(now())[:19].
K3 --- rnc
1
@ K3 --- rnc: Gracias. Actualizado por su sugerencia.
Steven Rumbalski
tras año 10000, una segunda será echado de menos
Diti
el tiempo lo dirá @diti;)
yǝsʞǝla
8

Yo suelo hacer:

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

# To print now:
print(now)

salida:

2019-01-13 14:40:28
An0n
fuente
7

Como no todas las datetime.datetimeinstancias tienen un componente de microsegundos (es decir, cuando es cero), puede dividir la cadena en un "." y tome solo el primer elemento, que siempre funcionará:

unicode(datetime.datetime.now()).partition('.')[0]
Austin Marshall
fuente
3

Podemos probar algo como a continuación

import datetime

date_generated = datetime.datetime.now()
date_generated.replace(microsecond=0).isoformat(' ').partition('+')[0]
Abhishek Bajaj
fuente
Esto es inferior a .isoformat(' ', 'seconds'), propuesto en una respuesta anterior.
davidchambers
1
Cuando intento la respuesta anterior propuesta anteriormente, obtengo el siguiente error >>> datetime.datetime.now (). Isoformat ('', 'segundos') Traceback (última llamada más reciente): Archivo "<stdin>", línea 1, en <module> TypeError: isoformat () toma como máximo 1 argumento (2 dados)
Abhishek Bajaj
Ah, ya veo. Funciona para mí en Python 3 pero no en Python 2.
davidchambers
Estoy usando la versión python 3.4.3, ya que veo ese error. >>> datetime.datetime.now (). isoformat ('', 'segundos') Traceback (última llamada más reciente): Archivo "<stdin>", línea 1, en <module> TypeError: isoformat () toma como máximo 1 argumento (2 dados)
Abhishek Bajaj
1

Encontré que esta es la forma más simple.

>>> 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
fuente
datetime.datetime.now (). strftime ("% Y-% m-% d% H:% M:% S") '2011-11-03 18:21:26' es mucho más fácil. Pero fácil no es siempre lo mejor
1919
1

Esto lo uso porque puedo entenderlo y, por lo tanto, recordarlo mejor (y el formato de fecha y hora también se puede personalizar según su elección):

import datetime
moment = datetime.datetime.now()
print("{}/{}/{} {}:{}:{}".format(moment.day, moment.month, moment.year,
                                 moment.hour, moment.minute, moment.second))
satyakam shashwat
fuente
Brillante. Simple, flexible e independiente de la plataforma (a diferencia del strftime).
Endre Ambos