Je n'ai jamais eu à convertir l'heure vers et depuis UTC. J'ai récemment reçu une demande pour que mon application soit au fuseau horaire, et je me tourne en rond. Beaucoup d'informations sur la conversion de l'heure locale en UTC, que j'ai trouvé assez élémentaire (peut-être que je fais aussi mal), mais je ne trouve aucune information sur la conversion facile de l'heure UTC en fuseau horaire des utilisateurs finaux.
En un mot, et l'application Android m'envoie des données (appengine app) et dans ces données est un horodatage. Pour stocker cet horodatage en heure UTC que j'utilise:
datetime.utcfromtimestamp(timestamp)
Cela semble fonctionner. Lorsque mon application stocke les données, elles sont stockées avec 5 heures d'avance (je suis EST -5)
Les données sont stockées sur BigTable d'Appengine, et lorsqu'elles sont récupérées, elles apparaissent sous forme de chaîne comme ceci:
"2011-01-21 02:37:21"
Comment convertir cette chaîne en DateTime dans le fuseau horaire correct des utilisateurs?
En outre, quel est le stockage recommandé pour les informations de fuseau horaire d'un utilisateur? (Comment stockez-vous généralement les informations tz, c'est-à-dire: "-5: 00" ou "EST", etc., etc.?) Je suis sûr que la réponse à ma première question peut contenir un paramètre et les réponses la seconde.
Réponses:
Si vous ne souhaitez pas fournir vos propres
tzinfo
objets, consultez la bibliothèque python-dateutil . Il fournit destzinfo
implémentations au-dessus d'une base de données zoneinfo (Olson) de sorte que vous pouvez faire référence aux règles de fuseau horaire par un nom quelque peu canonique.Modifier l' exemple développé pour l'afficher
strptime
utilisationModifier 2 Correction de l'utilisation de l'API pour afficher une meilleure méthode de point d'entrée
Modifier 3 méthodes de détection automatique incluses pour les fuseaux horaires (Yarin)
la source
dateutil.tz
et utilisertz.tzutc()
ettz.tzlocal()
comme fuseau horaire les objets que je cherchais. Il semble que la base de données de fuseau horaire sur mon système soit bonne (je me suis enregistré/usr/share/zoneinfo
). Je ne sais pas ce qui se passait.tz
module est le point d'entrée correct à utiliser pour cette bibliothèque. J'ai mis à jour ma réponse pour refléter cela. Ledateutil.zoneinfo
module que je montrais précédemment est utilisé en interne par letz
module comme solution de secours s'il ne peut pas localiser la base de données zoneinfo du système. Si vous regardez à l'intérieur de la bibliothèque, vous verrez qu'il y a un tarball DB zoneinfo dans le paquet qu'il utilise s'il ne trouve pas la base de données de votre système. Mon ancien exemple essayait de frapper directement cette base de données et je suppose que vous rencontriez des problèmes pour charger cette base de données privée (n'est-ce pas sur le chemin python en quelque sorte?)dateutil
, utilisezpytz
plutôt .Voici une méthode résiliente qui ne dépend d'aucune bibliothèque externe:
Cela évite les problèmes de synchronisation dans l'exemple de DelboyJay. Et le moindre problème de timing dans l'amendement d'Erik van Oosten.
Comme note de bas de page intéressante, le décalage de fuseau horaire calculé ci-dessus peut différer de l'expression apparemment équivalente suivante, probablement en raison des modifications des règles d'heure d'été:
Mettre à jour: cet extrait a la faiblesse d'utiliser le décalage UTC de l'heure actuelle, qui peut différer du décalage UTC du datetime d'entrée. Voir les commentaires sur cette réponse pour une autre solution.
Pour contourner les différents moments, saisissez le temps de l'époque à partir du temps passé. Voici ce que je fais:
la source
pytz
db similaire est impossible, voir PEP-431. Bien que vous puissiez écrire une solution stdlib uniquement qui fonctionne dans de tels cas sur des systèmes qui ont déjà un fuseau horaire historique, par exemple Linux, OS X, voyez ma réponse .utc_datetime
époque.Voir la documentation datetime sur tzinfo objets . Vous devez implémenter vous-même les fuseaux horaires que vous souhaitez prendre en charge. Voici des exemples au bas de la documentation.
Voici un exemple simple:
Production
la source
replace
pour définir le fuseau horaire sur GMT et le rendre "conscient", puis utilisezastimezone
pour convertir en un autre fuseau horaire.Si vous souhaitez obtenir le résultat correct même pour l'heure qui correspond à une heure locale ambiguë (par exemple, lors d'une transition DST) et / ou le décalage utc local est différent à différents moments de votre fuseau
pytz
horaire local, utilisez des fuseaux horaires:la source
Cette réponse devrait être utile si vous ne souhaitez pas utiliser d'autres modules en plus
datetime
.datetime.utcfromtimestamp(timestamp)
renvoie un naïfdatetime
objet (pas un objet conscient). Ceux qui sont conscients connaissent le fuseau horaire, et les naïfs ne le sont pas. Vous en voulez un si vous voulez convertir entre les fuseaux horaires (par exemple entre UTC et l'heure locale).Si vous n'êtes pas celui qui instancie la date pour commencer, mais vous pouvez toujours créer un
datetime
objet naïf en temps UTC, vous voudrez peut-être essayer ce code Python 3.x pour le convertir:Veillez à ne pas supposer par erreur que si votre fuseau horaire est actuellement MDT, l'heure d'été ne fonctionne pas avec le code ci-dessus car il imprime MST. Vous noterez que si vous changez le mois en août, il imprimera MDT.
Un autre moyen simple d'obtenir un
datetime
objet conscient (également en Python 3.x) est de le créer avec un fuseau horaire spécifié pour commencer. Voici un exemple, en utilisant UTC:Si vous utilisez Python 2.x, vous devrez probablement sous
datetime.tzinfo
- classer et utiliser cela pour vous aider à créer undatetime
objet conscient , car ildatetime.timezone
n'existe pas dans Python 2.x.la source
Si vous utilisez Django, vous pouvez utiliser la
timezone.localtime
méthode:la source
Vous pouvez utiliser la flèche
vous pouvez vous nourrir
arrow.get()
de tout. horodatage, chaîne iso, etc.la source
Je reporte traditionnellement cela au frontend - envoie les heures du backend sous forme d'horodatages ou d'un autre format datetime en UTC, puis laisse le client déterminer le décalage du fuseau horaire et restitue ces données dans le fuseau horaire approprié.
Pour une webapp, c'est assez facile à faire en javascript - vous pouvez comprendre le décalage de fuseau horaire du navigateur assez facilement en utilisant des méthodes intégrées, puis rendre correctement les données du backend.
la source
Vous pouvez utiliser
calendar.timegm
pour convertir votre temps en secondes depuis l'époque Unix ettime.localtime
pour reconvertir:Donne
Fri Jan 21 05:37:21 2011
(parce que je suis dans le fuseau horaire UTC + 03: 00).la source
par exemple, mon fuseau horaire est ' +08: 00 '. entrée utc = 2018-10-17T00: 00: 00.111Z , alors j'obtiendrai la sortie = 2018-10-17T08: 00: 00 + 08: 00
la source
À partir de la réponse ici , vous pouvez utiliser le module de temps pour convertir d'utc en heure locale définie sur votre ordinateur:
la source
Voici une version rapide et sale qui utilise les paramètres des systèmes locaux pour calculer le décalage horaire. REMARQUE: cela ne fonctionnera pas si vous devez convertir un fuseau horaire dans lequel votre système actuel ne fonctionne pas. J'ai testé cela avec les paramètres britanniques sous le fuseau horaire BST.
la source
datetime.fromtimestamp(ts)
: horodatage posix (secondes flottantes) -> objet datetime dans l'heure locale (cela fonctionne bien si le système d'exploitation se souvient des décalages utc passés pour le fuseau horaire local, c'est-à-dire sur Unix mais pas sur Windows pour les dates dans le passé)). Sinon, pytz pourrait être utilisé.offset = datetime.utcnow().replace(minute=0, second=0, microsecond=0) - datetime.now().replace(minute=0, second=0, microsecond=0)
j'ai obtenu des différences microsecondes étranges sans cela.datetime.fromtimestamp(ts)
au lieu de la réponse?Consolider la réponse de franksands en une méthode pratique.
la source