Digant C Kasundra
Ahora mismo tengo:
timestamp = datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S.%f')
Esto funciona muy bien a menos que esté convirtiendo una cadena que no tiene microsegundos. ¿Cómo puedo especificar que los microsegundos son opcionales (y deben considerarse 0 si no están en la cadena)?
Alejandro
Podrías usar un try/except
bloquear:
try:
timestamp = datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S.%f')
except ValueError:
timestamp = datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S')
-
Es un poco triste que esto dependa de excepciones como flujo de control.
–Joe Sadoski
15 de junio a las 13:50
-
@JoeSadoski No creo que la solución anterior se ajuste a lo que se describe en su artículo vinculado.
– Alejandro
15 de junio a las 15:33
¿Qué tal simplemente agregarlo si no existe?
if '.' not in date_string:
date_string = date_string + '.0'
timestamp = datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S.%f')
-
Esta es una buena respuesta, pero me decepciona que una biblioteca diseñada para eliminar el dolor de cabeza de transformar cadenas de fecha y hora en objetos de fecha y hora no se ocupe de estos casos de uso bastante simples. El objetivo de una biblioteca de este tipo es eliminar la necesidad de que el usuario se preocupe por esto.
– Auspicio
2 mayo 2018 a las 20:48
-
Me gusta mucho esta respuesta en lugar de usar el método try/catch
– francotirador
29 mayo 2019 a las 20:09
usuario14608345
Llego tarde a la fiesta, pero descubrí que si no te importan los bits opcionales, esto cortará el .%f
para ti.
datestring.split('.')[0]
-
Gracias. Esto funciona para mi caso de uso mucho mejor que otras soluciones de longitud
– vu le
17 de diciembre de 2020 a las 9:32
cuatro zorros de pelea
Prefiero usar coincidencias de expresiones regulares en lugar de probar y excepto. Esto permite muchas alternativas de formatos aceptables.
# full timestamp with milliseconds
match = re.match(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z", date_string)
if match:
return datetime.strptime(date_string, "%Y-%m-%dT%H:%M:%S.%fZ")
# timestamp missing milliseconds
match = re.match(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z", date_string)
if match:
return datetime.strptime(date_string, "%Y-%m-%dT%H:%M:%SZ")
# timestamp missing milliseconds & seconds
match = re.match(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}Z", date_string)
if match:
return datetime.strptime(date_string, "%Y-%m-%dT%H:%MZ")
# unknown timestamp format
return false
No olvide importar “re” y “datetime” para este método.
jfs
datetime(*map(int, re.findall('\d+', date_string)))
puede analizar ambos '%Y-%m-%d %H:%M:%S.%f'
y '%Y-%m-%d %H:%M:%S'
. Es demasiado permisivo si su entrada no se filtra.
Es rápido y sucio, pero a veces strptime()
es demasiado lento Se puede usar si sabe que la entrada tiene el formato de fecha esperado.
-
Esto da resultados incorrectos si, en
date_string
los ceros finales se omiten de la parte de microsegundos.– jez
22 de agosto de 2016 a las 19:07
-
@jez: sí, por eso dije que es “demasiado permisivo”. Funciona solo si la entrada tiene el formato esperado (ninguno o 6 dígitos para microsegundos). 2- sobre tu edición: mira la pregunta:
datetime
es la clase aquí, no el módulo.– jfs
22 de agosto de 2016 a las 19:14
milahu
usando una expresión regular y algunas expresiones de lista
time_str = "12:34.567"
# time format is [HH:]MM:SS[.FFF]
sum([a*b for a,b in zip(map(lambda x: int(x) if x else 0, re.match(r"(?:(\d{2}):)?(\d{2}):(\d{2})(?:\.(\d{3}))?", time_str).groups()), [3600, 60, 1, 1/1000])])
# result = 754.567
-
Esto da resultados incorrectos si, en
date_string
los ceros finales se omiten de la parte de microsegundos.– jez
22 de agosto de 2016 a las 19:07
-
@jez: sí, por eso dije que es “demasiado permisivo”. Funciona solo si la entrada tiene el formato esperado (ninguno o 6 dígitos para microsegundos). 2- sobre tu edición: mira la pregunta:
datetime
es la clase aquí, no el módulo.– jfs
22 de agosto de 2016 a las 19:14
julianwgs
Si está utilizando Pandas, también puede filtrar la serie y concatenarla. El índice se une automáticamente.
import pandas as pd
# Every other row has a different format
df = pd.DataFrame({"datetime_string": ["21-06-08 14:36:09", "21-06-08 14:36:09.50", "21-06-08 14:36:10", "21-06-08 14:36:10.50"]})
df["datetime"] = pd.concat([
pd.to_datetime(df["datetime_string"].iloc[1::2], format="%y-%m-%d %H:%M:%S.%f"),
pd.to_datetime(df["datetime_string"].iloc[::2], format="%y-%m-%d %H:%M:%S"),
])
fechahora_cadena | fecha y hora | |
---|---|---|
0 | 21-06-08 14:36:09 | 2021-06-08 14:36:09 |
1 | 21-06-08 14:36:09.50 | 2021-06-08 14:36:09.500000 |
2 | 21-06-08 14:36:10 | 2021-06-08 14:36:10 |
3 | 21-06-08 14:36:10.50 | 2021-06-08 14:36:10.500000 |