Sto analizzando il feed di avvisi del Servizio meteo nazionale in un'applicazione Web. Vorrei eliminare gli avvisi quando hanno raggiunto la loro scadenza. Mi piacerebbe anche visualizzare il tempo di scadenza nel formato orario locale per l'area geografica a cui appartengono.Conversione della stringa di data sensibile al fuso orario in UTC e ritorno in Python
Gli avvisi coprono l'intero USA, quindi penso che l'approccio migliore sia archiviare e confrontare le ore in timestamp UTC. Il tempo di scadenza arriva nel feed come una stringa come questa: 2011-09-09T22:12:00-04:00
.
sto usando le Labix dateutils pacchetto per analizzare la stringa in modo fuso orario-aware:
>>> from dateutil.parser import parse
>>> d = parse("2011-09-18T15:52:00-04:00")
>>> d
datetime.datetime(2011, 9, 18, 15, 52, tzinfo=tzoffset(None, -14400))
Sono anche in grado di catturare l'offset in ore UTC:
>>> offset_hours = (d.utcoffset().days * 86400 + d.utcoffset().seconds)/3600
>>> offset_hours
-4
Utilizzando le datetime.utctimetuple()
e time.mktime()
metodi, sono in grado di convertire la data analizzato per un timestamp UTC:
>>> import time
>>> expiration_utc_ts = time.mktime(d.utctimetuple())
>>> expiration_utc_ts
1316393520.0
A questo punto, mi sento abbastanza bene che sono in grado di convertire le stringhe non elaborate in un timestamp che rappresenta il tempo di scadenza in UTC. Sono in grado di confrontare l'ora corrente come un timestamp UTC della scadenza e determinare se ha bisogno di essere eliminati:
>>> now_utc_ts = time.mktime(time.gmtime())
>>> now_utc_ts
1316398744.0
>>> now_utc_ts >= expiration_tc_ts
True
La difficoltà che sto avendo sta cercando di convertire il mio timestamp UTC memorizzati nuovo all'originale formato localizzato. Ho le ore di offset memorizzati dalla conversione originale e una stringa ho analizzati per memorizzare l'etichetta fuso orario:
>>> print offset_hours
-4
>>> print timezone
EDT
mi piacerebbe convertire il timestamp UTC di nuovo ad un tempo formattato a livello locale, ma la conversione di nuovo a un datetime
non sembra funzionare:
>>> import datetime
>>> datetime.datetime.fromtimestamp(expiration_utc_ts) + datetime.timedelta(hours=offset_hours)
datetime.datetime(2011, 9, 18, 16, 52) # The hour is 16 but it should be 15
sembra come se fosse fuori di un'ora. Non sono sicuro di dove è stato introdotto l'errore? Ho messo insieme un altro test e ho ottenuto risultati simili:
>>> # Running this at 21:29pm EDT
>>> utc_now = datetime.datetime.utcnow()
>>> utc_now_ts = time.mktime(right_now.utctimetuple())
>>> datetime.datetime.fromtimestamp(utc_now_ts)
datetime.datetime(2011, 9, 18, 22, 29, 47) # Off by 1 hour
Qualcuno può aiutarmi a trovare il mio errore? Non sono sicuro che si tratti di un problema di risparmio giornaliero? Mi sono imbattuto in alcune cose che mi portano a credere che potrebbe essere il tentativo di localizzare le mie date e orari, ma a questo punto sono abbastanza perplesso. Speravo di fare tutti questi calcoli/confronti in un modo agnostico dal fuso orario.
possibile duplicato di [Problema con Python/pytz Conversione da fuso orario locale UTC poi di nuovo] (http://stackoverflow.com/questions/7465181/issue-with-python-pytz-converting- from-local-timezone-to-utc-then-back) – agf
Avrei pensato di poter fare tutto questo con oggetti datetime e non convertirli in tuple o timestamp. Se si crea un oggetto "ora" datetime time-aware, basta "se x
Speravo anch'io, ma PostgreSQL continuava a voler localizzare il valore datetime. (Sono sicuro che c'è un modo per aggirare questo, ma ho pensato che sarebbe stato più semplice adesso memorizzare solo i timestamp UTC) – Scott