datetime.datetime.utcnow()
Perché questo datetime
non ha alcuna informazione sul fuso orario dato che è esplicitamente un UTC datetime
?
Mi aspetto che ciò contenga tzinfo
.
datetime.datetime.utcnow()
Perché questo datetime
non ha alcuna informazione sul fuso orario dato che è esplicitamente un UTC datetime
?
Mi aspetto che ciò contenga tzinfo
.
Risposte:
Ciò significa che il fuso orario è ingenuo, quindi non puoi usarlo datetime.astimezone
puoi dargli un fuso orario come questo
import pytz # 3rd party: $ pip install pytz
u = datetime.utcnow()
u = u.replace(tzinfo=pytz.utc) #NOTE: it works only with a fixed utc offset
ora puoi cambiare i fusi orari
print(u.astimezone(pytz.timezone("America/New_York")))
Per ottenere l'ora corrente in un determinato fuso orario, puoi passare datetime.now()
direttamente a tzinfo :
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
print(datetime.now(pytz.timezone("America/New_York")))
Funziona per qualsiasi fuso orario, compresi quelli che osservano l'ora legale (DST), vale a dire, funziona per i fusi orari che possono avere offset utc diversi in momenti diversi (offset utc non fisso). Non utilizzare tz.localize(datetime.now())
: potrebbe non riuscire durante la transizione di fine ora legale quando l'ora locale è ambigua.
astimezone
. Quindi datetime non ha solo fusi orari nativi, ma l'unica implementazione ampiamente disponibile di tzinfo non è conforme al presunto standard.
u=datetime.now(pytz.utc)
tz.localize(datetime.now())
; usa datetime.now(tz)
invece.
Nota che per Python 3.2 in poi, il datetime
modulo contiene datetime.timezone
. La documentazione per datetime.utcnow()
dice:
Un datetime UTC corrente consapevole può essere ottenuto chiamando .
datetime.now
(
timezone.utc
)
Quindi puoi fare:
>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.utc)
datetime.now(timezone.utc)
o datetime.utcnow(timezone.utc)
?
datetime.utcnow()
non accetta argomenti. Quindi dovrebbe essere datetime.now(timezone.utc)
.
datetime.now()
restituirà l'ora della macchina ma datetime.utcnow()
restituirà l'ora UTC effettiva.
datetime.utcnow()
non è impostato tzinfo
per indicare che è UTC. Ma datetime.now(datetime.timezone.utc)
restituisce l'ora UTC con tzinfo
set.
tz
oggetto nel costruttore ora restituirà il tempo di quel fuso orario? Ok! Grazie per averlo segnalato.
Le librerie standard di Python non includono alcuna classe tzinfo (ma vedi pep 431 ). Posso solo indovinare i motivi. Personalmente penso che sia stato un errore non includere una classe tzinfo per UTC, perché quella non è abbastanza controversa da avere un'implementazione standard.
Modifica: sebbene non ci sia implementazione nella libreria, ce n'è una come esempio nella tzinfo
documentazione .
from datetime import timedelta, tzinfo
ZERO = timedelta(0)
# A UTC class.
class UTC(tzinfo):
"""UTC"""
def utcoffset(self, dt):
return ZERO
def tzname(self, dt):
return "UTC"
def dst(self, dt):
return ZERO
utc = UTC()
Per usarlo, per ottenere l'ora corrente come oggetto datetime consapevole:
from datetime import datetime
now = datetime.now(utc)
C'è datetime.timezone.utc
in Python 3.2+:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
datetime
oggetti creati da utcnow()
) ...
timezone.utc
è stato finalmente aggiunto a Python 3.2. Per compatibilità con le versioni precedenti, utcnow()
restituisce comunque un oggetto tempo senza fuso orario, ma puoi ottenere ciò che desideri chiamando now(timezone.utc)
.
struct
modulo farebbe conversioni automatiche da Unicode a bytestring e la decisione finale è stata quella di interrompere la compatibilità con le versioni precedenti di Python 3 per impedire che una decisione sbagliata potesse andare avanti.
tzinfo
documentazione di Python includa esempi di codice per implementarlo, ma non includono quella funzionalità nello stesso datetime! docs.python.org/2/library/datetime.html#datetime.tzinfo.fromutc
pytz
è un'ottima risorsa. Quando avevo modificato la mia risposta per inserire il codice di esempio, qualcun altro l'aveva già suggerito e non volevo rubare il tuono.
Il pytz
modulo è un'opzione e ce n'è un'altra python-dateutil
, che sebbene sia anche un pacchetto di terze parti, potrebbe già essere disponibile a seconda delle altre dipendenze e del sistema operativo.
Volevo solo includere questa metodologia come riferimento: se hai già installato python-dateutil
per altri scopi, puoi usarne tzinfo
invece di duplicarepytz
import datetime
import dateutil.tz
# Get the UTC time with datetime.now:
utcdt = datetime.datetime.now(dateutil.tz.tzutc())
# Get the UTC time with datetime.utcnow:
utcdt = datetime.datetime.utcnow()
utcdt = utcdt.replace(tzinfo=dateutil.tz.tzutc())
# For fun- get the local time
localdt = datetime.datetime.now(dateutil.tz.tzlocal())
Tendo a concordare sul fatto che le chiamate a utcnow
dovrebbero includere le informazioni sul fuso orario UTC. Ho il sospetto che questo non sia incluso perché la libreria di data e ora nativa è impostata su valori di tempo ingenui per compatibilità incrociata.
utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
datetime.now(pytz_tz)
che funziona sempre; datetime.now(dateutil.tz.tzlocal())
potrebbe non riuscire durante le transizioni di ora legale . PEP 495 - La disambiguazione dell'ora locale potrebbe migliorare la dateutil
situazione in futuro.
utc_dt = datetime.fromtimestamp(1234567890, dateutil.tz.tzutc())
(nota: dateutil
con un offset utc non fisso (come dateutil.tz.tzlocal()
) potrebbe non riuscire qui , utilizzare invece una pytz
soluzione basata su ).
dateutil
per dateutil.parser
, mi piaceva questa soluzione migliore. E 'stato così semplice come: utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc())
. Viola!!
Julien Danjou ha scritto un buon articolo spiegando perché non dovresti mai avere a che fare con i fusi orari . Un estratto:
In effetti, l'API datetime Python restituisce sempre oggetti datetime inconsapevoli, il che è molto sfortunato. Infatti, non appena ottieni uno di questi oggetti, non c'è modo di sapere quale sia il fuso orario, quindi questi oggetti sono abbastanza "inutili" da soli.
Purtroppo, anche se puoi usarlo utcnow()
, non vedrai ancora le informazioni sul fuso orario, come hai scoperto.
raccomandazioni:
Utilizzare sempre
datetime
oggetti consapevoli , ad esempio con informazioni sul fuso orario. Ciò garantisce che sia possibile confrontarli direttamente (glidatetime
oggetti consapevoli e inconsapevoli non sono confrontabili) e li restituirà correttamente agli utenti. Sfrutta pytz per avere oggetti fuso orario.Utilizzare ISO 8601 come formato stringa di input e output. Utilizzare
datetime.datetime.isoformat()
per restituire i timestamp come stringa formattata utilizzando quel formato, che include le informazioni sul fuso orario.Se è necessario analizzare stringhe contenenti timestamp formattati ISO 8601, è possibile fare affidamento su
iso8601
, che restituisce timestamp con le informazioni corrette sul fuso orario. Ciò rende i timestamp direttamente comparabili.
Per aggiungere timezone
informazioni in Python 3.2+
import datetime
>>> d = datetime.datetime.now(tz=datetime.timezone.utc)
>>> print(d.tzinfo)
'UTC+00:00'
AttributeError: 'module' object has no attribute 'timezone'
Python 2.7.13 (impostazione predefinita, 19 gennaio 2017, 14:48:08)
from datetime import datetime
from dateutil.relativedelta import relativedelta
d = datetime.now()
date = datetime.isoformat(d).split('.')[0]
d_month = datetime.today() + relativedelta(months=1)
next_month = datetime.isoformat(d_month).split('.')[0]
Le date UTC non richiedono alcuna informazione sul fuso orario poiché sono UTC, il che per definizione significa che non hanno offset.
pytz.utc
). Si noti che esiste una grande differenza tra un valore il cui offset da UTC è sconosciuto e uno in cui è noto che è 0. Quest'ultimo è ciò che utcnow()
dovrebbe restituire, IMO. Ciò si adatterebbe con "Un oggetto consapevole viene usato per rappresentare un momento specifico nel tempo che non è aperto all'interpretazione" come da documentazione.