web-dev-qa-db-fra.com

Comment convertir l'heure locale en UTC en Python?

Comment convertir une date/heure chaîne en heure locale en une chaîne en heure UTC?

Je suis sûr que j'ai déjà fait cela auparavant, mais je ne le trouve pas et SO m'aidera, espérons-le, ainsi que d'autres personnes à le faire à l'avenir.

Clarification: par exemple, si j'ai 2008-09-17 14:02:00 dans mon fuseau horaire local (+10), j'aimerais générer une chaîne avec l'équivalent UTC time: 2008-09-17 04:02:00.

De plus, dans http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ , notez qu'en général cela n'est pas possible, car avec DST et d'autres problèmes, il n'y a pas de conversion unique de l'heure locale à l'heure UTC.

248
Tom

Merci @rofly, la conversion complète de chaîne en chaîne est la suivante:

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

Mon résumé des fonctions time/calendar:

time.strptime
string -> Tuple (aucun fuseau horaire n'est appliqué, donc correspond à la chaîne)

time.mktime
heure locale Tuple -> secondes depuis Epoch (toujours heure locale)

time.gmtime
secondes depuis Epoch -> Tuple en UTC

et 

calendar.timegm
Tuple en UTC -> secondes depuis Epoch

time.localtime
secondes depuis l’époque -> Tuple dans le fuseau horaire local

60
Tom

Commencez par analyser la chaîne dans un objet datetime naïf. Il s'agit d'une instance de datetime.datetime sans information de fuseau horaire attachée. Consultez la documentation de datetime.strptime pour plus d'informations sur l'analyse de la chaîne de date.

Utilisez le module pytz , qui contient la liste complète des fuseaux horaires + UTC. Déterminez ce qu'est le fuseau horaire local, créez-en un objet, manipulez-le et associez-le à l'heure naïve.

Enfin, utilisez la méthode datetime.astimezone() pour convertir la date/heure en UTC.

Code source, utilisant le fuseau horaire local "America/Los_Angeles", pour la chaîne "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)

À partir de là, vous pouvez utiliser la méthode strftime() pour formater la date/heure UTC selon vos besoins:

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

La fonction utcnow () du module datetime peut être utilisée pour obtenir l'heure UTC actuelle.

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

Comme le lien mentionné ci-dessus par Tom: http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/ dit:

UTC est un fuseau horaire sans heure d'été et toujours un fuseau horaire sans changements de configuration dans le passé.

Mesurez et stockez toujours le temps en UTC

Si vous devez enregistrer où le temps a été pris, stockez-le séparément. Ne pas enregistrer l'heure locale + les informations sur le fuseau horaire!

NOTE - Si l'une de vos données se trouve dans une région qui utilise l'heure d'été, utilisez pytz et jetez un coup d'œil à la réponse de John Millikin.

Si vous souhaitez obtenir l'heure UTC à partir d'une chaîne donnée et que vous ayez la chance d'être dans une région du monde qui n'utilise pas l'heure d'été ou dont les données sont uniquement décalées par rapport à l'heure UTC sans application de l'heure d'été:

-> en utilisant l'heure locale comme base de la valeur de décalage:

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

-> Ou, à partir d'un offset connu, en utilisant 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'

Si vous êtes prêt à accepter des conversions de fuseaux horaires, lisez ceci:

https://medium.com/@eleroy/10-things-you-ne-to-know-about-date-and-time-in-python-with-datetime-pytz-dateutil-timedelta-309bfbafb3f7

111
monkut

Voici un résumé des conversions de temps Python courantes.

Certaines méthodes suppriment des fractions de secondes et sont marquées avec (s) . Une formule explicite telle que ts = (d - Epoch) / unit peut être utilisée à la place (merci jfs).

  • struct_time (UTC) → POSIX (s) :
    calendar.timegm(struct_time)
  • Date/heure naïve (locale) → POSIX (s) :
    calendar.timegm(stz.localize(dt, is_dst=None).utctimetuple())
    (exception lors des transitions DST, voir le commentaire de jfs)
  • Date/heure naïve (UTC) → POSIX (s) :
    calendar.timegm(dt.utctimetuple())
  • Datetime conscient → POSIX (s) :
    calendar.timegm(dt.utctimetuple())
  • POSIX → struct_time (UTC, s ):
    time.gmtime(t)
    (voir le commentaire de jfs)
  • Date/heure naïve (locale) → struct_time (UTC, s ):
    stz.localize(dt, is_dst=None).utctimetuple()
    (exception lors des transitions DST, voir le commentaire de jfs)
  • Date/heure naïve (UTC) → struct_time (UTC, s ):
    dt.utctimetuple()
  • Dateheure consciente → struct_time (UTC, s ):
    dt.utctimetuple()
  • POSIX → date naïve (locale):
    datetime.fromtimestamp(t, None)
    (peut échouer dans certaines conditions, voir le commentaire de jfs ci-dessous)
  • struct_time (UTC) → Date/heure naïve (locale, s ):
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
    (ne peut pas représenter des secondes intercalaires, voir le commentaire de jfs)
  • Date/heure naïve (UTC) → Date/heure naïve (locale):
    dt.replace(tzinfo=UTC).astimezone(tz).replace(tzinfo=None)
  • Dateetime consciente → Dateetime naïve (locale):
    dt.astimezone(tz).replace(tzinfo=None)
  • POSIX → date naïve (UTC):
    datetime.utcfromtimestamp(t)
  • struct_time (UTC) → Date/heure naïve (UTC, s ):
    datetime.datetime(*struct_time[:6])
    (ne peut pas représenter des secondes intercalaires, voir le commentaire de jfs)
  • Date/heure naïve (locale) → Date/heure naïve (UTC):
    stz.localize(dt, is_dst=None).astimezone(UTC).replace(tzinfo=None)
    (exception lors des transitions DST, voir le commentaire de jfs)
  • Datetime conscient → Dateetime naïve (UTC):
    dt.astimezone(UTC).replace(tzinfo=None)
  • POSIX → Date de prise de conscience:
    datetime.fromtimestamp(t, tz)
    (peut échouer pour les fuseaux horaires non-pytz)
  • struct_time (UTC) → Date et heure de connaissance (s) :
    datetime.datetime(struct_time[:6], tzinfo=UTC).astimezone(tz)
    (ne peut pas représenter des secondes intercalaires, voir le commentaire de jfs)
  • Date/heure naïve (locale) → Date et heure consciente:
    stz.localize(dt, is_dst=None)
    (exception lors des transitions DST, voir le commentaire de jfs)
  • Date/heure naïve (UTC) → Date et heure consciente:
    dt.replace(tzinfo=UTC)

Source: taaviburns.ca

34
akaihola
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)

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

Exemple d'utilisation de bd808 : Si votre source est un objet datetime.datetimet, appelez comme suit:

local_to_utc(t.timetuple())
23
Chuck Callebs

J'ai de la chance avec dateutil (qui est largement recommandé le SO pour d’autres questions connexes):

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

(Le code est dérivé de cette réponse à Convertit la chaîne de date/heure UTC en date/heure locale )

18
Yarin

Un autre exemple avec pytz, mais inclut localize (), ce qui m'a sauvé la journée.

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

J'ai eu le plus de succès avec 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
12
Shu Wu
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'
7
Scipythonee

si vous préférez 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")
5
user235042

Vous pouvez le faire avec:

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

Pour se déplacer à la lumière du jour, etc.

Aucune des réponses ci-dessus ne m'a particulièrement aidé. Le code ci-dessous fonctionne pour GMT.

def get_utc_from_local(date_time, local_tz=None):
    assert date_time.__class__.__== '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>)
2
Dantalion

Que diriez-vous - 

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

si secondes est None, il convertit l'heure locale en heure UTC, sinon convertit l'heure passée en heure UTC.

2
Anonymous fool

Utilisation de 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') 

Cette bibliothèque rend la vie facile :)

2
Yash

Simple

Je l'ai fait comme ça:

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

Mise en œuvre de fantaisie

Si vous voulez avoir envie, vous pouvez en faire un foncteur:

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

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

Résultat: 

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

En python3:

pip install python-dateutil

from dateutil.parser import tz

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

J'ai trouvé la meilleure réponse à une autre question ici . Il utilise uniquement les bibliothèques intégrées python et ne vous oblige pas à saisir votre fuseau horaire local (une exigence dans mon cas). 

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)

Je republie la réponse ici puisque cette question apparaît dans Google au lieu de la question liée en fonction des mots clés de la recherche.

0
franksands