2012-09-25 19 views
5

Estoy sacando una fecha de caducidad de cookie de Google Chrome. Por lo que parece, Chrome almacena las fechas de caducidad de las cookies con una marca de tiempo que usa 1601-01-01 00:00:00 UTC como la época. Mi implementación actual es la siguiente:Convertir la marca de tiempo microsegundo a fecha y hora en Python

stamp = int(result[3]) 
date = datetime.datetime.fromtimestamp(stamp/10000000.0) 
print date.year 

Sin embargo, esto está produciendo la fecha incorrecta (fuera de alrededor de un año). ¿Qué estoy haciendo mal aquí?

+2

puede ¿le da un ejemplo de marca de tiempo época y el correspondiente datetime esperado? – moooeeeep

+0

Además, '10000000.0' es por microsegundo, ¿verdad? –

+0

13022344559000000 - 30 AUG 2013 06:55 AM –

Respuesta

7

Otra opción, conseguir tzinfo de la librería estándar desde Python 3.2 (para las versiones anteriores de Python que puede obtener si de pytz):

>>> import pytz 
>>> from datetime import datetime, timedelta, timezone 
>>> epoch = datetime(1601, 1, 1, tzinfo=timezone.utc) 
>>> cookie_microseconds_since_epoch = 13022344559000000 
>>> cookie_datetime = epoch + timedelta(microseconds=cookie_microseconds_since_epoch) 
>>> str(cookie_datetime) 
'2013-08-29 13:55:59+00:00' 

Asumo que el La diferencia con respecto a su valor esperado es la compensación de zonas horarias.

Actualización:

Como @JFSebastian señala correctamente, si está utilizando UTC implícita ingenuosdatetime objetos, tzinfo es redundante y lo anterior se puede simplificar a:

>>> from datetime import datetime, timedelta 
>>> epoch = datetime(1601, 1, 1) 
>>> cookie_microseconds_since_epoch = 13022344559000000 
>>> cookie_datetime = epoch + timedelta(microseconds=cookie_microseconds_since_epoch) 
>>> str(cookie_datetime) 
'2013-08-30 13:55:59' 
+0

El año apropiado es 2013. ¿Por qué es el año de descanso por uno? –

+1

Porque lo basó en 1600 en lugar de 1601. – wberry

+0

Tienes razón. Se arregló el ejemplo para tener la época basada en 1601 correcta. –

1

No estoy seguro de qué datos está comenzando pero aquí hay un ejemplo que comienza a partir de una indicación de fecha y hora entera. Asume que el módulo pytz está presente (lo cual recomiendo mucho).

>>> import datetime, pytz 
>>> x = datetime.datetime.fromtimestamp(0) 
>>> x = x.replace(tzinfo=pytz.UTC) 
>>> str(x) 
'1970-01-01 00:00:00+00:00' 
>>> d = datetime.timedelta(365 * (1970 - 1601)) 
>>> str(x - d) 
'1601-03-31 00:00:00+00:00' 
>>> d = datetime.timedelta(365 * (1970 - 1601) + 31 + 28 + 31 - 1) 
>>> str(x - d) 
'1601-01-01 00:00:00+00:00' 
>>> str(d) 
'134774 days, 0:00:00' 

Así que ahí lo tienes. La conversión entre una época del 1 de enero de 1601 y una del 1 de enero de 1970 es de 134774 días.

¿Por qué ese número de días? ¡Años bisiestos! Agregamos una cierta cantidad de días, no años. (. De hecho, adding years is not directly supported en timedelta objetos)

+0

Esto funciona, pero creo que la solución de Pedro Romano, calcular con la época 1600-01-01 en lugar de calcular estáticamente la desviación de 134774 días y calcular con eso, es mejor (a menos que sea de algún modo un problema de rendimiento para una secuencia de comandos que necesita para ejecutar millones de veces o algo ...). – abarnert

+0

Debe ser aproximadamente el mismo en cuanto a rendimiento. A su manera, calcula la fecha de 1601 contra la época de 1970 y luego agrega su compensación de tiempo. De esta forma, tratas el tiempo compensado con respecto a 1970 y luego restas la diferencia entre épocas. – wberry

Cuestiones relacionadas