Manipuler des dates avec des fuseaux horaires en Python

Vous aviez une conférence téléphonique prévue pour le 21 décembre 2018, à 9 h 30, à Dubai. À quelle heure locale votre ami de Bangalore, en Inde, a-t-il dû se présenter pour y assister?

Pour presque tous les problèmes concernant les fuseaux horaires, vous devriez utiliser le module pytz. Ce package fournit la base de données des fuseaux horaires d’Olson, qui est la norme de facto pour les informations sur les fuseaux horaires disponibles dans de nombreuses langues et systèmes d’exploitation.

Une utilisation majeure de pytz est la localisation de dates simples créées avec la bibliothèque datetime. Par exemple, voici comment vous représenteriez une date à l’heure de Chicago:

>>> from datetime import datetime
>>> from pytz import timezone
>>> d = datetime(2018, 12, 21, 9, 30, 0)
>>> print(d)
2018-12-21 09:30:00
>>>

>>> # Localiser la date pour Chicago
>>> central = timezone('US/Central')
>>> loc_d = central.localize(d)
>>> print(loc_d)
2018-12-21 09:30:00-06:00
>>>

Une fois la date localisée, elle peut être convertie dans d’autres fuseaux horaires. Pour trouver la même heure à Bangalore, vous pouvez faire ça:

>>> # Converti à l'heure de Bangalore
>>> bang = loc_d.astimezone(timezone('Asia/Kolkata'))
>>> print(bang)
2018-12-21 21:00:00+05:30
>>>

Si vous voulez effectuer des calculs arithmétiques avec des dates localisées, vous devez être particulièrement attentif aux transitions d’heure d’été et autres détails.

Par exemple, en 2013, l’heure avancée des États-Unis a commencé le 13 mars à 2 h, heure locale (heure avancée d’une heure). Si vous faites des calculs naïfs, vous vous trompez. Par exemple:

>>> d = datetime(2018, 3, 10, 1, 45)
>>> dloc = central.localize(d)
>>> print(dloc)
2018-03-10 01:45:00-06:00
>>> ult= dloc+ timedelta(minutes=30)
>>> print(ult)
2018-03-10 02:15:00-06:00       # Erreur
>>>

La réponse est fausse parce qu’elle ne tient pas compte du saut d’une heure à l’heure locale. Pour corriger cela, utilisez la méthode normalize(). Par exemple:

>>> from datetime import timedelta
>>> ult = central.normalize(dloc+ timedelta(minutes=30))
>>> print(ult)
2018-03-10 03:15:00-05:00
>>>

Pour éviter que votre tête n’explose complètement, une stratégie commune pour la gestion des dates localisées consiste à convertir toutes les dates en heure UTC et à les utiliser pour tout stockage et manipulation internes. Par exemple:

>>> print(dloc)
2018-03-10 01:45:00-06:00
>>> dutc = dloc.astimezone(pytz.utc)
>>> print(dutc)
2018-03-10 07:45:00+00:00
>>>

Une fois à l’UTC, vous n’avez plus à vous soucier des problèmes liés à l’heure d’été et à d’autres questions. Ainsi, vous pouvez simplement effectuer l’arithmétique de date normale comme auparavant.

Si vous souhaitez éditer la date en heure localisée, il vous suffit de la convertir ensuite dans le fuseau horaire approprié. Par exemple:

>>> ult_utc = dutc + timedelta(minutes=30)
>>> print(ult_utc.astimezone(central))
2018-03-10 03:15:00-05:00
>>>

L’un des problèmes que pose le travail avec les fuseaux horaires consiste simplement à déterminer les noms de fuseaux horaires à utiliser.

Par exemple, comment savait-on que “Asia/Kolkata” était le bon nom de fuseau horaire pour l’Inde ? Pour le savoir, vous pouvez consulter le dictionnaire pytz.country_timezones en utilisant le code pays ISO 3166 comme clé. Par exemple:

>>> pytz.country_timezones['IN']
['Asia/Kolkata']
>>>

Au moment où vous lisez ceci, il est possible que le module pytz soit déprécié en faveur d’un meilleur support des fuseaux horaires, comme décrit dans PEP 431. Bon nombre des mêmes questions continueront toutefois de s’appliquer (p. ex. les avis utilisant les dates UTC, etc.).

LAISSER UN COMMENTAIRE

Please enter your comment!
Please enter your name here