web-dev-qa-db-fra.com

Comment imprimer une date/heure Python dans le fuseau horaire local?

Disons que j'ai une variable t qui est définie à ceci:

datetime.datetime(2009, 7, 10, 18, 44, 59, 193982, tzinfo=<UTC>)

Si je dis str(t), je reçois:

'2009-07-10 18:44:59.193982+00:00'

Comment puis-je obtenir une chaîne similaire, sauf imprimée dans le fuseau horaire local plutôt qu'en UTC?

17
mike

Pensez que vous devriez regarder autour de vous: datetime.astimezone ()

http://docs.python.org/library/datetime.html#datetime.datetime.astimezone

Voir aussi le module pytz - il est assez facile à utiliser - à titre d'exemple:

eastern = timezone('US/Eastern')

http://pytz.sourceforge.net/

Exemple:

from datetime import datetime
import pytz
from tzlocal import get_localzone # $ pip install tzlocal

utc_dt = datetime(2009, 7, 10, 18, 44, 59, 193982, tzinfo=pytz.utc)
print(utc_dt.astimezone(get_localzone())) # print local time
# -> 2009-07-10 14:44:59.193982-04:00
22
Mikhail Churbanov

Je pense que la meilleure façon de faire est d’utiliser la classe LocalTimezone définie dans la documentation datetime.tzinfo (goto http://docs.python.org/library/datetime.html#tzinfo-objects et faites défiler jusqu’à " Exemple de "classes tzinfo"):

En supposant que Local est une instance de LocalTimezone

t = datetime.datetime(2009, 7, 10, 18, 44, 59, 193982, tzinfo=utc)
local_t = t.astimezone(Local)

alors str(local_t) donne:

'2009-07-11 04:44:59.193982+10:00'

c'est ce que tu veux.

(Remarque: cela peut vous paraître étrange car je suis en Nouvelle-Galles du Sud, en Australie, à 10 ou 11 heures - en avance de UTC)

10
HughE

Ce script montre quelques façons d’afficher le fuseau horaire local à l’aide de astimezone():

#!/usr/bin/env python3

import pytz
from datetime import datetime, timezone
from tzlocal import get_localzone

utc_dt = datetime.now(timezone.utc)

PST = pytz.timezone('US/Pacific')
EST = pytz.timezone('US/Eastern')
JST = pytz.timezone('Asia/Tokyo')
NZST = pytz.timezone('Pacific/Auckland')

print("Pacific time {}".format(utc_dt.astimezone(PST).isoformat()))
print("Eastern time {}".format(utc_dt.astimezone(EST).isoformat()))
print("UTC time     {}".format(utc_dt.isoformat()))
print("Japan time   {}".format(utc_dt.astimezone(JST).isoformat()))

# Use astimezone() without an argument
print("Local time   {}".format(utc_dt.astimezone().isoformat()))

# Use tzlocal get_localzone
print("Local time   {}".format(utc_dt.astimezone(get_localzone()).isoformat()))

# Explicitly create a pytz timezone object
print("Local time   {}".format(utc_dt.astimezone(NZST).isoformat()))

Il génère les éléments suivants:

$ ./timezones.py 
Pacific time 2019-02-22T17:54:14.957299-08:00
Eastern time 2019-02-22T20:54:14.957299-05:00
UTC time     2019-02-23T01:54:14.957299+00:00
Japan time   2019-02-23T10:54:14.957299+09:00
Local time   2019-02-23T14:54:14.957299+13:00
Local time   2019-02-23T14:54:14.957299+13:00
Local time   2019-02-23T14:54:14.957299+13:00

Notez que l'appel de astimezone() sans objet timezone est défini par défaut sur la zone locale. Cela signifie que vous n'avez pas besoin d'importer tzlocal. Je ne suis pas tout à fait sûr que cela soit toujours sûr par rapport à l'utilisation de tzlocal get_localzone, peut-être que quelqu'un peut commenter?

0
htaccess

J'ai écrit quelque chose comme ça l'autre jour:

import time, datetime
def nowString():
    # we want something like '2007-10-18 14:00+0100'
    mytz="%+4.4d" % (time.timezone / -(60*60) * 100) # time.timezone counts westwards!
    dt  = datetime.datetime.now()
    dts = dt.strftime('%Y-%m-%d %H:%M')  # %Z (timezone) would be empty
    nowstring="%s%s" % (dts,mytz)
    return nowstring

Donc la partie intéressante pour vous est probablement la ligne commençant par "mytz = ...". time.timezone renvoie le fuseau horaire local, mais avec le signe opposé à UTC. Donc, il est écrit "-3600" pour exprimer UTC + 1.

Malgré son ignorance vis-à-vis de l'heure d'été (DST, voir commentaire), je laisse cette question aux personnes qui manipulent time.timezone.

0
ThomasH

J'utilise cette fonction datetime_to_local_timezone(), qui semble trop compliquée, mais je n'ai trouvé aucune version plus simple d'une fonction qui convertit une instance datetime en fuseau horaire local, telle que configurée dans Operating System , avec le décalage UTC présent effect à ce moment-là :

import time, datetime

def datetime_to_local_timezone(dt):
    Epoch = dt.timestamp() # Get POSIX timestamp of the specified datetime.
    st_time = time.localtime(Epoch) #  Get struct_time for the timestamp. This will be created using the system's locale and it's time zone information.
    tz = datetime.timezone(datetime.timedelta(seconds = st_time.tm_gmtoff)) # Create a timezone object with the computed offset in the struct_time.

    return dt.astimezone(tz) # Move the datetime instance to the new time zone.

utc = datetime.timezone(datetime.timedelta())
dt1 = datetime.datetime(2009, 7, 10, 18, 44, 59, 193982, utc) # DST was in effect
dt2 = datetime.datetime(2009, 1, 10, 18, 44, 59, 193982, utc) # DST was not in effect

print(dt1)
print(datetime_to_local_timezone(dt1))

print(dt2)
print(datetime_to_local_timezone(dt2))

Cet exemple affiche quatre dates. Pendant deux instants, l'un en janvier et l'autre en juillet 2009, chacun imprime l'horodatage une fois en heure UTC et une fois dans le fuseau horaire local. Ici, où CET (UTC + 01: 00) est utilisé en hiver et CEST (UTC + 02: 00) en été, il affiche les informations suivantes:

2009-07-10 18:44:59.193982+00:00
2009-07-10 20:44:59.193982+02:00

2009-01-10 18:44:59.193982+00:00
2009-01-10 19:44:59.193982+01:00
0
Feuermurmel

A partir de python 3.2, n'utilisant que les fonctions de bibliothèque standard:

u_tm = datetime.datetime.utcfromtimestamp(0)
l_tm = datetime.datetime.fromtimestamp(0)
l_tz = datetime.timezone(l_tm - u_tm)

t = datetime.datetime(2009, 7, 10, 18, 44, 59, 193982, tzinfo=l_tz)
str(t)
'2009-07-10 18:44:59.193982-07:00'

Juste besoin d'utiliser l_tm - u_tm ou u_tm - l_tm selon que vous voulez afficher en + ou - heures à partir de l'heure UTC. Je suis dans MST, d'où vient le -07. Un code plus intelligent devrait pouvoir déterminer le moyen de soustraire.

Et seulement besoin de calculer le fuseau horaire local une fois. Cela ne va pas changer. Au moins jusqu'à ce que vous passiez de/à l'heure avancée.

0
mMerlin