Python-Impostazione di un datetime in un fuso orario specifico (senza conversioni UTC)
Domanda
Solo per essere chiari, questo è python 2.6, sto usando pytz.
Questo è per un'applicazione che si occupa solo di fusi orari statunitensi, ho bisogno di essere in grado di ancorare una data (oggi) e ottenere un timestamp unix (epoch time) per 8pm e 11pm solo in PST.
Questo mi sta facendo impazzire.
> pacific = pytz.timezone("US/Pacific")
> datetime(2011,2,11,20,0,0,0,pacific)
datetime.datetime(2011, 2, 11, 20, 0, tzinfo=<DstTzInfo 'US/Pacific' PST-1 day, 16:00:0 STD>)
> datetime(2011,2,11,20,0,0,0,pacific).strftime("%s")
'1297454400'
zsh> date -d '@1297454400'
Fri Feb 11 12:00:00 PST 2011
Quindi, anche se sto impostando un fuso orario e creando il datetime con quel fuso orario, lo sta ancora creando come UTC e quindi convertendolo.Questo è più un problema poiché UTC sarà un giorno avanti quando sto cercando di fare i calcoli.
C'è un modo semplice (o almeno sensico) per generare un timestamp per 8pm PST oggi?
(per essere chiari, capisco il valore dell'utilizzo di UTC nella maggior parte delle situazioni, come i timestamp del database o per l'archiviazione generale.Questa non è una di quelle situazioni, ho specificamente bisogno di un timestamp per la sera in PST, e UTC non dovrebbe entrare in esso.)
Soluzione
Creare un oggetto tzinfo utc
per il fuso orario UTC, prova questo:
#XXX: WRONG (for any timezone with a non-fixed utc offset), DON'T DO IT
datetime(2011,2,11,20,0,0,0,pacific).astimezone(utc).strftime("%s")
Modificare: Come sottolineato nei commenti, inserendo il fuso orario nel datetime
il costruttore non è sempre robusto.Il metodo preferito utilizzando il documentazione pytz sarebbe:
pacific.localize(datetime(2011,2,11,20,0,0,0)).astimezone(utc).strftime("%s")
Si noti inoltre dai commenti che strftime("%s")
non è affidabile, è ignorare le informazioni sul fuso orario (anche UTC) e presuppone il fuso orario del sistema su cui è in esecuzione.Si basa su un'implementazione della libreria C sottostante e non funziona affatto su alcuni sistemi (ad es.Windows).
Altri suggerimenti
Ci sono almeno due problemi:
- .
- Non è necessario passare un fuso orario con offset UTC non fisso come
"US/Pacific"
come parametro TZINFO direttamente.Dovresti Utilizzare il metodopytz.timezone("US/Pacific").localize()
invece -
.strftime('%s')
non è portatile, Ignora Tzinfo , e usa sempre il fuso orario locale.Utilizzaredatetime.timestamp()
o I suoi analoghi sulle versioni di Python più anziane invece.Per effettuare un datetime consapevole del fuso orario nel timezone specificato:
.#!/usr/bin/env python from datetime import datetime import pytz # $ pip install pytz tz = pytz.timezone("US/Pacific") aware = tz.localize(datetime(2011, 2, 11, 20), is_dst=None)
Per ottenere il timestamp posix:
.timestamp = (aware - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()
(su Python 2.6, Vedi la funzione
totimestamp()
su come emulare il metodo.total_seconds()
).