2012-09-25 32 views
9

Tengo un calendario de javascript que me envía unixtimestamp. Estoy en Singapur. Quiero que esta marca de tiempo sea interpretada como una marca de tiempo de Singapur y luego convertida a utc para comparaciones con el db.Marca de tiempo de Unix a fecha y hora en django con zona horaria

No puedo, por mi propia vida, descubrir cómo decirle a django que esta marca de tiempo pertenece a la zona horaria actual, Singapur.

cuando lo haga una declaración de impresión de la marca de tiempo, se añade 8 horas a la vez (lo que significa que Django piensa entrada I el tiempo en UTC y está localizando al contexto de Singapur)

Entre muchas otras cosas , he intentado: start=datetime.datetime.fromtimestamp(int(start_date)).replace(tzinfo=get_current_timezone())

el fecha_inicial es 1325376000 (que se traduce en 2012-01-01 00:00:00)

Sin embargo, al imprimir la salida de este recibo 2012-01-01 08 : 00: 00 + 06: 55. Ni siquiera sé de dónde viene +06: 55 cuando Singapur es +08: 00. Estoy muy perdido.

Gracias por su ayuda.

settings.py:

TIME_ZONE = 'Asia/Singapore'

USE_TZ = True

+0

posix timestamp '1325376000' es' '2012-01-01 00:00:00 UTC + 0000'' y '' 2012-01-01 08:00:00 SGT + 0800''. ¿Por qué crees que debería ser '00: 00: 00' en Singapur? – jfs

Respuesta

13

Suponiendo que tienes instalado pytz:

from datetime import datetime 
import pytz 
local_tz = pytz.timezone("Asia/Singapore") 
utc_dt = datetime.utcfromtimestamp(timestamp).replace(tzinfo=pytz.utc) 
local_dt = local_tz.normalize(utc_dt.astimezone(local_tz)) 

Por ejemplo:

>>> from datetime import datetime 
>>> import pytz 
>>> local_tz = pytz.timezone("Asia/Singapore") 
>>> utc_dt = datetime.utcfromtimestamp(1325376000).replace(tzinfo=pytz.utc) 
>>> utc_dt 
datetime.datetime(2012, 1, 1, 0, 0, tzinfo=<UTC>) 
>>> local_dt = local_tz.normalize(utc_dt.astimezone(local_tz)) 
>>> local_dt 
datetime.datetime(2012, 1, 1, 8, 0, tzinfo=<DstTzInfo 'Asia/Singapore' SGT+8:00:00 STD>) 
>>> local_dt.replace(tzinfo=None) 
datetime.datetime(2012, 1, 1, 8, 0) 
+0

¡Gracias! Funciona perfectamente. – nknj

+0

¿Qué parte de mi respuesta depende de la zona horaria del servidor? Además, 'tz.localize (dt)' de 'pytz' es idéntico (en este caso) a' tz.normalize (dt.replace (tzinfo = pytz.utc) .astimezone (tz)) ': http: // pytz.sourceforge.net/#localized-times-and-date-arithmetic –

+2

FFUUU! Ahh, gracias! Tienes razón. Soy un idiota. Mi respuesta ha sido actualizada para dar la respuesta correcta y real. –

4

Pase el pytz tzinfo objeto a fromtimestamp() método:

#!/usr/bin/env python 
from datetime import datetime 
import pytz # $ pip install pytz 

tz = pytz.timezone("Asia/Singapore") 
print(datetime.fromtimestamp(1325376000, tz)) 
# -> 2012-01-01 08:00:00+08:00 

Nota: el objeto resultado es consciente de zona horaria: se podría comparar con otros objetos de fecha y hora conscientes, es decir, que no es necesario convertirlo a UTC para comparar, puedes usarlo tal cual.

Ni siquiera sé de dónde viene +06: 55 cuando singapore es +08: 00.

Usted ve +06:55 debido a la llamada no válida .replace(). get_current_timezone() devuelve pytz.timezone("Asia/Singapore") que tiene un desplazamiento utc variable (puede tener un desplazamiento utc diferente en diferentes fechas). Cuando llama al .replace() un poco al azar (depende de la implementación) se utiliza el objeto tzinfo. El problema es que el método .replace() no permite que pytz.timezone("Asia/Singapore") elija el tzinfo correcto para la fecha de entrada.

>>> list(tz._tzinfos.values()) 
[<DstTzInfo 'Asia/Singapore' MALT+7:00:00 STD>, 
<DstTzInfo 'Asia/Singapore' MALT+7:20:00 STD>, 
<DstTzInfo 'Asia/Singapore' JST+9:00:00 STD>, 
<DstTzInfo 'Asia/Singapore' SMT+6:55:00 STD>, 
<DstTzInfo 'Asia/Singapore' SGT+7:30:00 STD>, 
<DstTzInfo 'Asia/Singapore' MALT+7:30:00 STD>, 
<DstTzInfo 'Asia/Singapore' MALST+7:20:00 DST>, 
<DstTzInfo 'Asia/Singapore' LMT+6:55:00 STD>, 
<DstTzInfo 'Asia/Singapore' SGT+8:00:00 STD>] 

es decir, tanto +06:55 y +0800 son válidos (en diferentes fechas) para Singapur. Es por eso que debe usar .replace() solo con zonas horarias que tienen un desplazamiento de utc constante, como la zona horaria utc en sí (el desplazamiento es cero, siempre para cualquier fecha).

fromtimestamp(,tz) El método llama internamente al tz.fromutc() que permite que tz elija la compensación correcta para un tiempo utc dado.

Cuestiones relacionadas