2012-09-25 15 views
9

Ho un calendario javascript che mi manda un unixtimestamp. Sono a Singapore. Voglio che questo timestamp per essere interpretato come un timestamp Singapore e poi convertito in UTC per i confronti con il db.Unix timestamp a datetime in Django con fuso orario

non posso, per la vita di me stesso, capire come raccontare Django che questa volta timbro è il fuso orario corrente, Singapore.

Quando faccio una dichiarazione stampa del timestamp, aggiunge 8 ore per il tempo (il che significa che Django pensa ingresso I il tempo in UTC ed è localizzarla al contesto di Singapore)

Tra le molte altre cose , ho provato: start=datetime.datetime.fromtimestamp(int(start_date)).replace(tzinfo=get_current_timezone())

lo start_date è 1.325.376 mila (che si traduce in 2012-01-01 00:00:00)

Tuttavia, quando stampo l'uscita di questo ho 2012-01-01 08 : 00: 00 + 06: 55. Io non so nemmeno dove +06: 55 proviene da quando Singapore è +08: 00. Sono così perso.

Grazie per il vostro aiuto.

settings.py:

TIME_ZONE = 'Asia/Singapore'

USE_TZ = True

+0

timestamp posix '1325376000' è' '2012-01-01 00:00:00 UTC + 0000'' e '' 2012-01-01 08:00:00 SGT + 0800''. Perché pensi che dovrebbe essere "00: 00: 00" a Singapore? – jfs

risposta

13

Supponendo che hai installato 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)) 

Ad esempio:

>>> 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

Grazie! Funziona perfettamente. – nknj

+0

Quale parte della mia risposta dipende dal fuso orario del server? Inoltre, 'tz.localize (dt)' di pytz' è identico (in questo caso) a 'tz.normalize (dt.replace (tzinfo = pytz.utc) .astimezone (tz))': http: // pytz.sourceforge.net/#localized-times-and-date-arithmetic –

+2

FFUUU! Ahh, grazie! Hai ragione. Sono un idiota. La mia risposta è stata aggiornata per dare la risposta vera e corretta. –

4

Passare l'pytz tzinfo oggetto da fromtimestamp() metodo:

#!/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: l'oggetto risultato è fuso orario-aware: si potrebbe confrontarlo con altri oggetti datetime consapevoli Per esempio, non è necessario convertirlo in UTC per confronto - puoi usarlo così com'è.

io non so nemmeno dove +06: 55 proviene da quando Singapore è +08: 00.

Si vede +06:55 a causa della chiamata non valida .replace(). get_current_timezone() restituisce pytz.timezone("Asia/Singapore") con offset variabile dell'utc (potrebbe avere un offset dell'utc diverso in date diverse). Quando si chiama .replace() di qualche casuale (dipende dall'implementazione) tzinfo oggetto viene utilizzato. Il problema è che il metodo .replace() non consente a pytz.timezone("Asia/Singapore") di scegliere il tzinfo corretto per la data di inserimento.

>>> 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>] 

cioè sia +06:55 e +0800 valgono (in date differenti) per Singapore. Ecco perché è necessario utilizzare .replace() solo con fusi orari che hanno un offset utc costante come il fuso orario utc stesso (l'offset è zero, sempre per qualsiasi data).

fromtimestamp(,tz) chiamate di metodo tz.fromutc() internamente che consente a tz di scegliere l'offset corretto per un dato tempo di utc.