2010-08-04 14 views
11

Necesito convertir una cadena en un objeto datetime, junto con los segundos fraccionarios. Me encuentro con varios problemas.cadena a fecha y hora fraccional, en Google App Engine

Normalmente, yo haría:

>>> datetime.datetime.strptime(val, "%Y-%m-%dT%H:%M:%S.%f") 

Pero los errores y documentos viejos me mostró strptime de que no tiene python2.5% f ...

Al investigar más, parece que la App Engine al almacén de datos no le gustan los segundos fraccionarios. Tras la edición de una entidad del almacén de datos, se trata de añadir 0,5 al campo de fecha y hora me dio el siguiente error:

ValueError: unconverted data remains: .5 

dudo que las fracciones de segundo no son compatibles ... así que esto es sólo en el visor del almacén de datos, ¿verdad?

¿Alguien ha eludido este problema? Quiero utilizar los objetos nativos datetime ... Prefiero no almacenar marcas de tiempo UNIX ...

¡Gracias!


EDIT: Gracias a Jacob Oscarson por la .replace (...) tip!

Una cosa a tener en cuenta es verificar la longitud de nofrag antes de alimentarlo. Diferentes fuentes usan diferente precisión por segundos.

Aquí es una función rápida para aquellos que buscan algo similar:

def strptime(val): 
    if '.' not in val: 
     return datetime.datetime.strptime(val, "%Y-%m-%dT%H:%M:%S") 

    nofrag, frag = val.split(".") 
    date = datetime.datetime.strptime(nofrag, "%Y-%m-%dT%H:%M:%S") 

    frag = frag[:6] # truncate to microseconds 
    frag += (6 - len(frag)) * '0' # add 0s 
    return date.replace(microsecond=int(frag)) 
+0

Gracias! Realmente estaba buscando algo similar. =) – PEZ

Respuesta

11

de análisis

Sin el apoyo %f formato para datetime.datetime.strptime() todavía se puede suficientemente fácil entrar en un objeto datetime.datetime (escoger al azar un valor para su val aquí) usando datetime.datetime.replace()), probado en 2.5.5:

>>> val = '2010-08-06T10:00:14.143896' 
>>> nofrag, frag = val.split('.') 
>>> nofrag_dt = datetime.datetime.strptime(nofrag, "%Y-%m-%dT%H:%M:%S") 
>>> dt = nofrag_dt.replace(microsecond=int(frag)) 
>>> dt 
datetime.datetime(2010, 8, 6, 10, 0, 14, 143896) 

Ahora tiene su objeto datetime.datetime.

Almacenamiento

lectura más en http://code.google.com/appengine/docs/python/datastore/typesandpropertyclasses.html#datetime

no veo mencionar que las fracciones no son compatibles, por lo que sí, es probable que sólo el espectador almacén de datos. Los documentos apuntan directamente a los documentos del módulo de Python 2.5.2 para datetime, y admite fracciones, pero no la directiva de análisis %f para strptime. Consultando fracciones podría ser más complicado, aunque ..

+0

¡Gracias por la respuesta!En realidad, consultar con fracciones parece funcionar bien. Hice un par de pruebas rápidas y definitivamente dice la diferencia entre milisegundos. – jbenet

2

historia antigua por ahora, pero en estos tiempos modernos también se puede utilizar convenientemente dateutil

from dateutil import parser as DUp 

funky_time_str = "1/1/2011 12:51:00.AM" 

foo = DUp.parse(funky_time_str) 

print foo.timetuple() 
# time.struct_time(tm_year=2011, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=51, tm_sec=0, tm_wday=5, tm_yday=1, tm_isdst=-1) 

print foo.microsecond 
# 12300 

print foo 
# 2011-01-01 00:51:00.

dateutil es compatible con una sorprendente variedad de posibles formatos de entrada, que se analiza sin cadenas de patrones.

+2

* "en estos tiempos modernos" *, 'datetime.strptime (val,"% Y-% m-% dT% H:% M:% S.% f ")' funciona como está. – jfs