Domanda

Come converto un datetime stringa nell'ora locale ad a stringa nell'ora UTC?

Sono sicuro di averlo già fatto prima, ma non riesco a trovarlo e spero che SO possa aiutare me (e altri) a farlo in futuro.

Una precisazione:Ad esempio, se ho 2008-09-17 14:02:00 nel mio fuso orario locale (+10), vorrei generare una stringa con l'equivalente UTC tempo: 2008-09-17 04:02:00.

Anche da http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/, tieni presente che in generale ciò non è possibile poiché con l'ora legale e altri problemi non esiste una conversione univoca dall'ora locale all'ora UTC.

È stato utile?

Soluzione 3

Grazie @rofly, la conversione completa da stringa a stringa è la seguente:

time.strftime("%Y-%m-%d %H:%M:%S", 
              time.gmtime(time.mktime(time.strptime("2008-09-17 14:04:00", 
                                                    "%Y-%m-%d %H:%M:%S"))))

Il mio riassunto del time/calendar funzioni:

time.strptime
stringa --> tupla (nessun fuso orario applicato, quindi corrisponde alla stringa)

time.mktime
tupla dell'ora locale --> secondi trascorsi dall'epoca (sempre ora locale)

time.gmtime
secondi dall'epoca --> tupla in UTC

E

calendar.timegm
tupla in UTC --> secondi dall'epoca

time.localtime
secondi dall'epoca --> tupla nel fuso orario locale

Altri suggerimenti

Innanzitutto, analizza la stringa in un oggetto datetime ingenuo.Questo è un esempio di datetime.datetime senza informazioni sul fuso orario allegate.Consulta la documentazione per datetime.strptime per informazioni sull'analisi della stringa della data.

Usa il pytz modulo, che viene fornito con un elenco completo di fusi orari + UTC.Scopri qual è il fuso orario locale, costruisci un oggetto fuso orario da esso e manipolalo e collegalo all'ingenuo datetime.

Infine, usa datetime.astimezone() metodo per convertire la data/ora in UTC.

Codice sorgente, utilizzando il fuso orario locale "America/Los_Angeles", per la stringa "2001-2-3 10:11:12":

import pytz, datetime
local = pytz.timezone ("America/Los_Angeles")
naive = datetime.datetime.strptime ("2001-2-3 10:11:12", "%Y-%m-%d %H:%M:%S")
local_dt = local.localize(naive, is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc)

Da lì è possibile utilizzare il file strftime() metodo per formattare la data/ora UTC secondo necessità:

utc_dt.strftime ("%Y-%m-%d %H:%M:%S")

Il modulo datetime utcnow() la funzione può essere utilizzata per ottenere l'ora UTC corrente.

>>> import datetime
>>> utc_datetime = datetime.datetime.utcnow()
>>> utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2010-02-01 06:59:19'

Come il collegamento menzionato sopra da Tom: http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ dice:

UTC è un fuso orario senza tempo di salvataggio dell'ora legale e ancora un fuso orario senza modifiche alla configurazione in passato.

Misura e memorizza sempre il tempo in UTC.

Se è necessario registrare il luogo in cui è stato impiegato il tempo, memorizzarlo separatamente. Non memorizza l'ora locale + le informazioni sul fuso orario!

NOTA - Se uno qualsiasi dei tuoi dati si trova in una regione che utilizza l'ora legale, utilizza pytz e dai un'occhiata alla risposta di John Millikin.

Se desideri ottenere l'ora UTC da una determinata stringa e sei abbastanza fortunato da trovarti in una regione del mondo che non utilizza l'ora legale o che disponi di dati che sono solo compensati da UTC senza l'ora legale applicata:

--> utilizzando l'ora locale come base per il valore di offset:

>>> # Obtain the UTC Offset for the current system:
>>> UTC_OFFSET_TIMEDELTA = datetime.datetime.utcnow() - datetime.datetime.now()
>>> local_datetime = datetime.datetime.strptime("2008-09-17 14:04:00", "%Y-%m-%d %H:%M:%S")
>>> result_utc_datetime = local_datetime + UTC_OFFSET_TIMEDELTA
>>> result_utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2008-09-17 04:04:00'

--> Oppure, da un offset noto, utilizzando datetime.timedelta():

>>> UTC_OFFSET = 10
>>> result_utc_datetime = local_datetime - datetime.timedelta(hours=UTC_OFFSET)
>>> result_utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2008-09-17 04:04:00'

AGGIORNAMENTO:

Da Python 3.2 datetime.timezone è disponibile.È possibile generare un oggetto datetime con riconoscimento del fuso orario con il comando seguente:

import datetime

timezone_aware_dt = datetime.datetime.now(datetime.timezone.utc)

Se sei pronto per affrontare le conversioni del fuso orario, leggi questo:

https://medium.com/@eleroy/10-cose-che-devi-sapere-su-data-e-ora-in-python-con-datetime-pytz-dateutil-timedelta-309bfbafb3f7

Ecco un riepilogo delle conversioni temporali comuni di Python.

Alcuni metodi eliminano frazioni di secondo e sono contrassegnati con (S).Una formula esplicita come ts = (d - epoch) / unit può essere usato invece (grazie jfs).

  • struct_time (UTC) → POSIX (S):
    calendar.timegm(struct_time)
  • Datetime ingenuo (locale) → POSIX (S):
    calendar.timegm(stz.localize(dt, is_dst=None).utctimetuple())
    (eccezione durante le transizioni dell'ora legale, vedere il commento di jfs)
  • Datetime ingenuo (UTC) → POSIX (S):
    calendar.timegm(dt.utctimetuple())
  • Datetime consapevole → POSIX (S):
    calendar.timegm(dt.utctimetuple())
  • POSIX → struct_time (UTC, S):
    time.gmtime(t)
    (vedi commento di jfs)
  • Datetime ingenuo (locale) → struct_time (UTC, S):
    stz.localize(dt, is_dst=None).utctimetuple()
    (eccezione durante le transizioni dell'ora legale, vedere il commento di jfs)
  • Datetime naïve (UTC) → struct_time (UTC, S):
    dt.utctimetuple()
  • Datetime consapevole → struct_time (UTC, S):
    dt.utctimetuple()
  • POSIX → Datetime ingenuo (locale):
    datetime.fromtimestamp(t, None)
    (potrebbe fallire in determinate condizioni, vedere il commento di jfs di seguito)
  • struct_time (UTC) → Datetime naïve (locale, S):
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
    (non può rappresentare i secondi intercalari, vedi commento di jfs)
  • Datetime naïve (UTC) → Datetime naïve (locale):
    dt.replace(tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
  • Datetime consapevole → Datetime ingenuo (locale):
    dt.astimezone(tz).replace(tzinfo=None)
  • POSIX → Data/ora naïve (UTC):
    datetime.utcfromtimestamp(t)
  • struct_time (UTC) → Datetime naïve (UTC, S):
    datetime.datetime(*struct_time[:6])
    (non può rappresentare i secondi intercalari, vedi commento di jfs)
  • Datetime naïve (locale) → Datetime naïve (UTC):
    stz.localize(dt, is_dst=None).astimezone(UTC).replace(tzinfo=None)
    (eccezione durante le transizioni dell'ora legale, vedere il commento di jfs)
  • Datetime consapevole → Datetime naïve (UTC):
    dt.astimezone(UTC).replace(tzinfo=None)
  • POSIX → Data/ora consapevole:
    datetime.fromtimestamp(t, tz)
    (potrebbe fallire per fusi orari non Pytz)
  • struct_time (UTC) → Datetime consapevole (S):
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz)
    (non può rappresentare i secondi intercalari, vedi commento di jfs)
  • Datetime ingenuo (locale) → Datetime consapevole:
    stz.localize(dt, is_dst=None)
    (eccezione durante le transizioni dell'ora legale, vedere il commento di jfs)
  • Datetime naïve (UTC) → Datetime consapevole:
    dt.replace(tzinfo=UTC)

Fonte: taaviburns.ca

def local_to_utc(t):
    secs = time.mktime(t)
    return time.gmtime(secs)

def utc_to_local(t):
    secs = calendar.timegm(t)
    return time.localtime(secs)

Fonte: http://feihonghsu.blogspot.com/2008/02/converting-from-local-time-to-utc.html

Esempio di utilizzo da bd808:Se la tua fonte è a datetime.datetime oggetto t, chiamare come:

local_to_utc(t.timetuple())

Ho molta fortuna con dateutil (che è ampiamente raccomandato su SO per altre domande correlate):

from datetime import *
from dateutil import *
from dateutil.tz import *

# METHOD 1: Hardcode zones:
utc_zone = tz.gettz('UTC')
local_zone = tz.gettz('America/Chicago')
# METHOD 2: Auto-detect zones:
utc_zone = tz.tzutc()
local_zone = tz.tzlocal()

# Convert time string to datetime
local_time = datetime.strptime("2008-09-17 14:02:00", '%Y-%m-%d %H:%M:%S')

# Tell the datetime object that it's in local time zone since 
# datetime objects are 'naive' by default
local_time = local_time.replace(tzinfo=local_zone)
# Convert time to UTC
utc_time = local_time.astimezone(utc_zone)
# Generate UTC time string
utc_string = utc_time.strftime('%Y-%m-%d %H:%M:%S')

(Il codice è stato derivato da questa risposta a Converte la stringa data/ora UTC in data/ora locale)

Un altro esempio con pytz, ma include localize(), che mi ha salvato la giornata.

import pytz, datetime
utc = pytz.utc
fmt = '%Y-%m-%d %H:%M:%S'
amsterdam = pytz.timezone('Europe/Amsterdam')

dt = datetime.datetime.strptime("2012-04-06 10:00:00", fmt)
am_dt = amsterdam.localize(dt)
print am_dt.astimezone(utc).strftime(fmt)
'2012-04-06 08:00:00'

Ho avuto più successo con python-dateutil:

from dateutil import tz

def datetime_to_utc(date):
    """Returns date in UTC w/o tzinfo"""
    return date.astimezone(tz.gettz('UTC')).replace(tzinfo=None) if date.tzinfo else date
import time

import datetime

def Local2UTC(LocalTime):

    EpochSecond = time.mktime(LocalTime.timetuple())
    utcTime = datetime.datetime.utcfromtimestamp(EpochSecond)

    return utcTime

>>> LocalTime = datetime.datetime.now()

>>> UTCTime = Local2UTC(LocalTime)

>>> LocalTime.ctime()

'Thu Feb  3 22:33:46 2011'

>>> UTCTime.ctime()

'Fri Feb  4 05:33:46 2011'

se preferisci datetime.datetime:

dt = datetime.strptime("2008-09-17 14:04:00","%Y-%m-%d %H:%M:%S")
utc_struct_time = time.gmtime(time.mktime(dt.timetuple()))
utc_dt = datetime.fromtimestamp(time.mktime(utc_struct_time))
print dt.strftime("%Y-%m-%d %H:%M:%S")

Puoi farlo con:

>>> from time import strftime, gmtime, localtime
>>> strftime('%H:%M:%S', gmtime()) #UTC time
>>> strftime('%H:%M:%S', localtime()) # localtime

Che ne dite di -

time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(seconds))

se secondi è None quindi converte l'ora locale in tempo UTC altrimenti converte il tempo trascorso in UTC.

Semplice

L'ho fatto in questo modo:

>>> utc_delta = datetime.utcnow()-datetime.now()
>>> utc_time = datetime(2008, 9, 17, 14, 2, 0) + utc_delta
>>> print(utc_time)
2008-09-17 19:01:59.999996

Implementazione fantasiosa

Se vuoi essere fantasioso, puoi trasformarlo in un funtore:

class to_utc():
    utc_delta = datetime.utcnow() - datetime.now()

    def __call__(cls, t):
        return t + cls.utc_delta

Risultato:

>>> utc_converter = to_utc()
>>> print(utc_converter(datetime(2008, 9, 17, 14, 2, 0)))
2008-09-17 19:01:59.999996

Per aggirare l'ora legale, ecc.

Nessuna delle risposte sopra mi ha aiutato particolarmente.Il codice seguente funziona per GMT.

def get_utc_from_local(date_time, local_tz=None):
    assert date_time.__class__.__name__ == 'datetime'
    if local_tz is None:
        local_tz = pytz.timezone(settings.TIME_ZONE) # Django eg, "Europe/London"
    local_time = local_tz.normalize(local_tz.localize(date_time))
    return local_time.astimezone(pytz.utc)

import pytz
from datetime import datetime

summer_11_am = datetime(2011, 7, 1, 11)
get_utc_from_local(summer_11_am)
>>>datetime.datetime(2011, 7, 1, 10, 0, tzinfo=<UTC>)

winter_11_am = datetime(2011, 11, 11, 11)
get_utc_from_local(winter_11_am)
>>>datetime.datetime(2011, 11, 11, 11, 0, tzinfo=<UTC>)

Utilizzando http://crsmithdev.com/arrow/

arrowObj = arrow.Arrow.strptime('2017-02-20 10:00:00', '%Y-%m-%d %H:%M:%S' , 'US/Eastern')

arrowObj.to('UTC') or arrowObj.to('local') 

Questa libreria semplifica la vita :)

In Python3:

pip install python-dateutil

from dateutil.parser import tz

mydt.astimezone(tz.gettz('UTC')).replace(tzinfo=None) 

Ho trovato la risposta migliore su un'altra domanda Qui.Utilizza solo le librerie integrate Python e non richiede l'inserimento del fuso orario locale (un requisito nel mio caso)

import time
import calendar

local_time = time.strptime("2018-12-13T09:32:00.000", "%Y-%m-%dT%H:%M:%S.%f")
local_seconds = time.mktime(local_time)
utc_time = time.gmtime(local_seconds)

Sto ripubblicando la risposta qui poiché questa domanda appare su Google invece della domanda collegata a seconda delle parole chiave di ricerca.

in questo caso ...pytz è la migliore lib

import pytz
utc = pytz.utc
yourdate = datetime.datetime.now()
yourdateutc = yourdate.astimezone(utc).replace(tzinfo=None)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top