417 votes

Comment convertir une chaîne d'heure locale en UTC ?

Comment convertir une date chaîne de caractères en heure locale à un chaîne de caractères en temps UTC ?

Je suis sûr que j'ai déjà fait cela auparavant, mais je n'arrive pas à le retrouver et le SO m'aidera (ainsi que d'autres) à le faire à l'avenir.

Clarification : Par exemple, si j'ai 2008-09-17 14:02:00 dans mon fuseau horaire local ( +10 ), je voudrais générer une chaîne de caractères avec l'équivalent de UTC temps : 2008-09-17 04:02:00 .

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

1 votes

Sachez que la méthode mktime() prend en entrée une "heure locale" qui peut ne pas correspondre à ce que vous attendez, je l'ai utilisé et cela a tout gâché. Jetez un coup d'œil à ce lien

376voto

John Millikin Points 86775

Tout d'abord, il faut analyser la chaîne en un objet datetime naïf. Il s'agit d'une instance de datetime.datetime sans information sur le fuseau horaire. Voir son documentation .

Utilisez le pytz qui est livré avec une liste complète de fuseaux horaires + UTC. Déterminer le fuseau horaire local, construire un objet fuseau horaire à partir de celui-ci, le manipuler et l'attacher au datetime naïf.

Enfin, utilisez datetime.astimezone() pour convertir la date en UTC.

Code source, utilisant le fuseau horaire local "America/Los_Angeles", pour la chaîne "2001-2-3 10:11:12" :

from datetime import datetime   
import pytz

local = pytz.timezone("America/Los_Angeles")
naive = 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 le strftime() pour formater la date UTC selon les besoins :

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

7 votes

Veuillez modifier votre réponse avec le code suivant : [code]local.localize(naive)[/code] Voir le document : enlace Malheureusement, l'utilisation de l'argument tzinfo des constructeurs standard de datetime ''ne fonctionne pas'' avec pytz pour de nombreux fuseaux horaires. >>> datetime(2002, 10, 27, 12, 0, 0, tzinfo=amsterdam).strftime(fmt) '2002-10-27 12:00:00 AMT+0020'

2 votes

Apparemment, l'étape "déterminer le fuseau horaire local" s'avère plus difficile qu'il n'y paraît (pratiquement impossible).

4 votes

Utilisez le fichier local.localize comme suggéré par @SamStoelinga, sinon vous ne tiendrez pas compte de l'heure d'été.

234voto

monkut Points 14549

NOTE -- À partir de 2020, vous ne devriez pas utiliser .utcnow() o .utcfromtimestamp(xxx) . Comme vous êtes probablement passé à python3, vous devriez utiliser des objets datetime tenant compte des fuseaux horaires.

>>> from datetime import timezone
>>> 
>>> # alternative to '.utcnow()'
>>> dt_now = datetime.datetime.now(datetime.timezone.utc)
>>>
>>> # alternative to '.utcfromtimestamp()'
>>> dt_ts = datetime.fromtimestamp(1571595618.0, tz=timezone.utc)

pour les détails, voir : voir : https://blog.ganssle.io/articles/2019/11/utcnow.html

réponse originale (de 2010) :

Le module datetime utcnow() 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 changement de configuration dans le passé.

Toujours mesurer et stocker le temps en UTC .

Si vous devez enregistrer le lieu où le temps a été pris, stockez-le séparément. Ne pas stocker 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 la méthode suivante pytz et jetez un coup d'oeil à la réponse de John Millikin.

Si vous voulez obtenir l'heure UTC à partir d'une chaîne de caractères donnée et que vous avez la chance de vous trouver dans une région du monde qui n'utilise pas l'heure d'été, ou que vous avez des données qui sont seulement décalées par rapport à l'heure UTC sans application de l'heure d'été :

--> en utilisant l'heure locale comme base pour 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 décalage 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'

UPDATE :

Depuis python 3.2 datetime.timezone est disponible. Vous pouvez générer un objet datetime avec fuseau horaire en utilisant la commande ci-dessous :

import datetime

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

Si vous êtes prêt à vous attaquer aux conversions de fuseaux horaires, lisez ceci :

https://medium.com/@eleroy/10-choses-que-vous-devez-savoir-sur-la-date-et-le-temps-dans-python-avec-le-temps-date-pytz-dateutil-timedelta-309bfbafb3f7

20 votes

Cela ne convertit que l'heure actuelle. Je dois prendre n'importe quelle heure (sous forme de chaîne) et la convertir en UTC.

0 votes

Je ne pense pas que cela soit important ici, si vous utilisez des valeurs de décalage standard. local_time = utc_time + utc_offset AND utc_time = local_time - utc_offset.

5 votes

Cela ne fonctionne qu'avec l'heure actuelle, car les horodatages passés et futurs peuvent avoir un décalage UTC différent en raison de l'heure d'été.

71voto

Tom Points 8420

Merci @rofly, la conversion complète de chaîne à 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é de la time / calendar fonctions :

time.strptime
string --> tuple (pas de fuseau horaire appliqué, donc correspond à la chaîne)

time.mktime
local time tuple --> secondes depuis l'époque (toujours en heure locale)

time.gmtime
secondes depuis l'époque --> tuple en UTC

y

calendar.timegm
tuple en UTC --> secondes depuis l'époque

time.localtime
secondes depuis l'époque --> tuple dans le fuseau horaire local

4 votes

(always local time) semble être erronée : l'entrée de mktime() est l'heure locale, la sortie est les secondes depuis l'époque ( 1970-01-01 00:00:00 +0000 (UTC) ) qui ne dépend pas du fuseau horaire.

3 votes

Il y a aussi 50% de chance qu'il tombe en panne pendant le passage à l'heure d'été. Voir Problèmes avec l'heure locale

24voto

Chuck Callebs Points 8084
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-local-time-to-utc.html

Exemple d'utilisation de bd808 : Si votre source est un datetime.datetime objet t appeler comme :

local_to_utc(t.timetuple())

5 votes

Si votre source est un objet datetime.datetime t appel sous la forme : local_to_utc(t.timetuple())

2 votes

.timetuple() postes d'appel tm_isdst a -1 il y a 50% de chance mktime() échoue pendant la transition DST.

1 votes

La solution de Chuck perd des informations à la milliseconde.

20voto

Encore un exemple avec pytz, mais qui inclut localize(), ce qui a sauvé ma 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'

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X