trouver un expert Python
Travailler avec des dates et des heures est l'un des plus grands défis de la programmation. Entre les fuseaux horaires, l'heure d'été et les différents formats de date écrits, il peut être difficile de garder une trace des jours et des heures auxquels vous faites référence. Heureusement, le Python intégré datetime
Le module peut vous aider à gérer la nature complexe des dates et des heures.
Dans ce didacticiel, vous apprendrez:
- Pourquoi programmer avec dates et heures est un tel défi
- Quelles fonctions sont disponibles dans le Python
datetime
module - Comment imprimer ou lire une date et une heure dans un format spécifique
- Comment faire arithmétique avec dates et heures
De plus, vous allez développer une application soignée pour décompter le temps restant jusqu'à la prochaine PyCon US!
Commençons!
Programmation avec dates et heures
Si vous avez déjà travaillé sur un logiciel qui devait suivre les temps dans plusieurs zones géographiques, vous comprenez probablement pourquoi la programmation avec le temps peut être si difficile. La déconnexion fondamentale est que les programmes informatiques préfèrent des événements parfaitement ordonnés et réguliers, mais la manière dont la plupart des humains utilisent et se réfèrent au temps est très irrégulière.
Remarque: Si vous souhaitez en savoir plus sur les raisons pour lesquelles le temps peut être si compliqué à gérer, il existe de nombreuses ressources disponibles sur le Web. Voici quelques bons endroits pour commencer:
Un bon exemple de cette irrégularité est heure d'été. Aux États-Unis et au Canada, les horloges sont avancées d'une heure le deuxième dimanche de mars et reculées d'une heure le premier dimanche de novembre. Cependant, ce n'est le cas que depuis 2007. Avant 2007, les horloges étaient avancées le premier dimanche d'avril et reculées le dernier dimanche d'octobre.
Les choses deviennent encore plus compliquées quand on considère fuseaux horaires. Idéalement, les limites des fuseaux horaires suivraient exactement les lignes de longitude. Cependant, pour des raisons historiques et politiques, les lignes de fuseau horaire sont rarement droites. Souvent, les zones séparées par de grandes distances se trouvent dans le même fuseau horaire et les zones adjacentes se trouvent dans des fuseaux horaires différents. Il y a des fuseaux horaires avec des formes assez funky.
Comment les ordinateurs comptent le temps
Presque tous les ordinateurs comptent le temps à partir d'un instant appelé Époque Unix. Cela s'est produit le 1er janvier 1970 à 00 h 00 UTC. UTC signifie Temps universel coordonné et se réfère à l'heure à une longitude de 0 °. L'UTC est souvent aussi appelé Greenwich Mean Time, ou GMT. L'UTC n'est pas ajusté pour l'heure d'été, il conserve donc constamment vingt-quatre heures par jour.
Par définition, le temps Unix s'écoule au même rythme que UTC, donc un pas d'une seconde en UTC correspond à un pas d'une seconde en temps Unix. Vous pouvez généralement déterminer la date et l'heure en UTC d'un instant donné depuis le 1er janvier 1970, en comptant le nombre de secondes depuis l'époque Unix, à l'exception de secondes intercalaires. Des secondes intercalaires sont parfois ajoutées à l’UTC pour tenir compte du ralentissement de la rotation de la Terre, mais ne sont pas ajoutées au temps Unix.
Remarque: Il y a un bug intéressant associé au temps Unix. Étant donné que de nombreux systèmes d'exploitation plus anciens sont 32 bits, ils stockent l'heure Unix dans un entier signé 32 bits.
Cela signifie qu'à 03:14:07 le 19 janvier 2038, l'entier débordera, entraînant ce que l'on appelle le problème de l'année 2038, ou Y2038. Semblable au problème Y2K, Y2038 devra être corrigé pour éviter des conséquences catastrophiques pour les systèmes critiques.
Presque tous les langages de programmation, y compris Python, incorporent le concept du temps Unix. La bibliothèque standard de Python comprend un module appelé temps
qui peut imprimer le nombre de secondes depuis l'époque Unix:
>>> importation temps
>>> temps.temps()
1579718137.550164
Dans cet exemple, vous importez le temps
module et exécuter temps()
pour imprimer le temps Unix, ou le nombre de secondes (hors secondes intercalaires) depuis l'époque.
En plus du temps Unix, les ordinateurs ont besoin d'un moyen de transmettre des informations de temps aux utilisateurs. Comme vous l'avez vu dans le dernier exemple, le temps Unix est presque impossible pour un humain à analyser. Au lieu de cela, l'heure Unix est généralement convertie en UTC, qui peut ensuite être convertie en heure locale à l'aide de décalages de fuseau horaire.
le Internet Assigned Numbers Authority (IANA) maintient une base de données de toutes les valeurs des décalages de fuseau horaire. L'IANA publie également des mises à jour régulières qui incluent toute modification des décalages de fuseau horaire. Cette base de données est souvent incluse avec votre système d'exploitation, bien que certaines applications puissent inclure une copie mise à jour.
La base de données contient une copie de tous les fuseaux horaires désignés et combien d'heures et de minutes ils sont décalés par rapport à l'UTC. Ainsi, pendant l'hiver, lorsque l'heure d'été n'est pas en vigueur, le fuseau horaire de l'Est américain a un décalage de -05: 00, ou cinq heures négatives par rapport à UTC. D'autres régions ont des décalages différents, qui peuvent ne pas être des heures entières. Le décalage UTC pour le Népal, par exemple, est de +05: 45, ou positif à cinq heures et quarante-cinq minutes de l'UTC.
Comment signaler les dates standard
Le temps Unix est la façon dont les ordinateurs comptent le temps, mais il serait incroyablement inefficace pour les humains de déterminer le temps en calculant le nombre de secondes à partir d'une date arbitraire. Au lieu de cela, nous travaillons en termes d'années, de mois, de jours, etc. Mais même avec ces conventions en place, une autre couche de complexité vient du fait que les différentes langues et cultures ont différentes manières d'écrire la date.
Aux États-Unis, par exemple, les dates sont généralement écrites en commençant par le mois, puis le jour, puis l'année. Cela signifie que le 31 janvier 2020 est écrit comme suit: 31-01-2020. Cela correspond étroitement à la version écrite longue de la date.
Cependant, la plupart des pays d'Europe et de nombreuses autres régions écrivent la date en commençant par le jour, puis le mois, puis l'année. Cela signifie que le 31 janvier 2020 est écrit comme suit: 31-01-2020. Ces différences peuvent provoquer toutes sortes de confusion lors de la communication entre les cultures.
Pour éviter les erreurs de communication, l'Organisation internationale de normalisation (ISO) a développé ISO 8601. Cette norme spécifie que toutes les dates doivent être écrites dans l'ordre des données les plus importantes aux moins importantes. Cela signifie que le format est l'année, le mois, le jour, l'heure, la minute et la seconde:
Dans cet exemple, Aaaa
représente une année à quatre chiffres, et MM
et DD
sont le mois et le jour à deux chiffres, commençant par un zéro si nécessaire. Après ça, HH
, MM
, et SS
représentent les heures, les minutes et les secondes à deux chiffres, en commençant par un zéro si nécessaire.
L'avantage de ce format est que la date peut être représentée sans ambiguïté. Dates écrites comme JJ-MM-AAAA
ou MM-JJ-AAAA
peut être mal interprété si le jour est un numéro de mois valide. Vous verrez un peu plus tard comment utiliser le format ISO 8601 avec Python datetime
.
Comment le temps devrait être stocké dans votre programme
La plupart des développeurs qui ont travaillé avec le temps ont entendu les conseils pour convertir l'heure locale en UTC et stocker cette valeur pour référence ultérieure. Dans de nombreux cas, en particulier lorsque vous stockez des dates du passé, ces informations sont suffisantes pour effectuer l’arithmétique nécessaire.
Cependant, un problème peut se produire si un utilisateur de votre programme entre une date future dans son heure locale. Les règles de fuseau horaire et d'heure d'été changent assez fréquemment, comme vous l'avez vu précédemment avec le changement de 2007 en heure d'été pour les États-Unis et le Canada. Si les règles de fuseau horaire de l'emplacement de votre utilisateur changent avant la date future qu'il a entrée, l'UTC ne fournira pas suffisamment d'informations pour revenir à l'heure locale correcte.
Remarque: Il existe un certain nombre d'excellentes ressources disponibles pour vous aider à déterminer la manière appropriée de stocker les données de temps dans votre application. Voici quelques points de départ:
Dans ce cas, vous devez stocker l'heure locale, y compris le fuseau horaire, que l'utilisateur a entrée ainsi que la version de la base de données de fuseau horaire IANA qui était en vigueur lorsque l'utilisateur a enregistré l'heure. De cette façon, vous pourrez toujours convertir l'heure locale en UTC. Cependant, cette approche ne vous permettra pas toujours de convertir UTC à l'heure locale correcte.
Utiliser le Python datetime
Module
Comme vous pouvez le voir, travailler avec des dates et des heures dans la programmation peut être compliqué. Heureusement, vous avez rarement besoin d'implémenter des fonctionnalités compliquées à partir de zéro de nos jours car de nombreuses bibliothèques open-source sont disponibles pour vous aider. C'est certainement le cas en Python, qui comprend trois modules distincts dans la bibliothèque standard pour travailler avec les dates et les heures:
calendrier
génère des calendriers et fournit des fonctions à l'aide d'un calendrier grégorien idéalisé.datetime
fournit des cours pour manipuler les dates et les heures.temps
fournit des fonctions liées au temps où les dates ne sont pas nécessaires.
Dans ce didacticiel, vous vous concentrerez sur l'utilisation de Python datetime
module. L'objectif principal de datetime
consiste à simplifier l'accès aux attributs de l'objet liés aux dates, heures et fuseaux horaires. Étant donné que ces objets sont si utiles, calendrier
renvoie également des instances de classes de datetime
.
temps
est moins puissant et plus compliqué à utiliser que datetime
. De nombreuses fonctions temps
retourner un spécial struct_time
exemple. Cet objet possède une interface de tuple nommée pour accéder aux données stockées, ce qui le rend similaire à une instance de datetime
. Cependant, il ne prend pas en charge toutes les fonctionnalités de datetime
, en particulier la possibilité d'effectuer une arithmétique avec des valeurs de temps.
datetime
fournit trois classes qui composent l'interface de haut niveau que la plupart des gens utiliseront:
datetime.date
est une date idéalisée qui suppose que le calendrier grégorien s'étend à l'infini dans le futur et le passé. Cet objet stocke lean
,mois
, etjournée
comme attributs.datetime.time
est un temps idéal qui suppose qu'il y a 86 400 secondes par jour sans seconde intercalaire. Cet objet stocke leheure
,minute
,seconde
,microseconde
, ettzinfo
(informations sur le fuseau horaire).datetime.datetime
est une combinaison d'unDate
et untemps
. Il possède tous les attributs des deux classes.
Création de Python datetime
Instances
Les trois classes qui représentent les dates et les heures datetime
avoir similaire initialiseurs. Ils peuvent être instanciés en passant des arguments de mots clés pour chacun des attributs, tels que an
, Date
, ou heure
. Vous pouvez essayer le code ci-dessous pour avoir une idée de la façon dont chaque objet est créé:
>>> de datetime importation Date, temps, datetime
>>> Date(an=2020, mois=1, journée=31)
datetime.date (2020, 1, 31)
>>> temps(heure=13, minute=14, seconde=31)
datetime.time (13, 14, 31)
>>> datetime(an=2020, mois=1, journée=31, heure=13, minute=14, seconde=31)
datetime.datetime (2020, 1, 31, 13, 14, 31)
Dans ce code, vous importez les trois classes principales de datetime
et instancier chacun d'eux en passant des arguments au constructeur. Vous pouvez voir que ce code est quelque peu bavard, et si vous n'avez pas les informations dont vous avez besoin sous forme d'entiers, ces techniques ne peuvent pas être utilisées pour créer datetime
instances.
Heureusement, datetime
fournit plusieurs autres moyens pratiques de créer datetime
instances. Ces méthodes ne vous obligent pas à utiliser des entiers pour spécifier chaque attribut, mais vous permettent à la place d'utiliser d'autres informations:
date d'aujourd'hui()
crée undatetime.date
par exemple avec la date locale actuelle.datetime.now ()
crée undatetime.datetime
par exemple avec la date et l'heure locales actuelles.datetime.combine ()
combine des instances dedatetime.date
etdatetime.time
en un seuldatetime.datetime
exemple.
Ces trois façons de créer datetime
les instances sont utiles lorsque vous ne savez pas à l'avance quelles informations vous devez transmettre aux initialiseurs de base. Vous pouvez essayer ce code pour voir comment fonctionnent les autres initialiseurs:
>>> de datetime importation Date, temps, datetime
>>> aujourd'hui = Date.aujourd'hui()
>>> aujourd'hui
datetime.date (2020, 1, 24)
>>> maintenant = datetime.maintenant()
>>> maintenant
datetime.datetime (2020, 1, 24, 14, 4, 57, 10015)
>>> heure actuelle = temps(maintenant.heure, maintenant.minute, maintenant.seconde)
>>> datetime.combiner(aujourd'hui, heure actuelle)
datetime.datetime (2020, 1, 24, 14, 4, 57)
Dans ce code, vous utilisez date d'aujourd'hui()
, datetime.now ()
, et datetime.combine ()
pour créer des instances de Date
, datetime
, et temps
objets. Chaque instance est stockée dans une variable différente:
aujourd'hui
est unDate
instance qui n'a que l'année, le mois et le jour.maintenant
est undatetime
instance qui a l'année, le mois, le jour, l'heure, la minute, la seconde et les microsecondes.heure actuelle
est untemps
instance dont l'heure, la minute et la seconde ont les mêmes valeurs quemaintenant
.
Sur la dernière ligne, vous combinez les informations de date dans aujourd'hui
avec les informations de temps dans heure actuelle
pour produire un nouveau datetime
exemple.
Attention: datetime
fournit également datetime.utcnow ()
, qui renvoie une instance de datetime
à l'UTC actuelle. Cependant, la documentation Python recommande de ne pas utiliser cette méthode car elle n'inclut aucune information de fuseau horaire dans l'instance résultante.
En utilisant datetime.utcnow ()
peut produire des résultats surprenants lors de l'arithmétique ou des comparaisons entre datetime
instances. Dans une section ultérieure, vous verrez comment attribuer des informations de fuseau horaire à datetime
instances.
Utilisation de chaînes pour créer Python datetime
Instances
Une autre façon de créer Date
instances est d'utiliser .fromisoformat ()
. Pour utiliser cette méthode, vous fournissez une chaîne avec la date au format ISO 8601 que vous avez connue plus tôt. Par exemple, vous pouvez fournir une chaîne avec l'année, le mois et la date spécifiés:
Cette chaîne représente la date du 31 janvier 2020, selon le format ISO 8601. Vous pouvez créer un Date
par exemple avec l'exemple suivant:
>>> de datetime importation Date
>>> Date.fromisoformat("2020-01-31")
datetime.date (2020, 1, 31)
Dans ce code, vous utilisez date.fromisoformat ()
créer un Date
par exemple pour le 31 janvier 2020. Cette méthode est très utile car elle est basée sur la norme ISO 8601. Mais que faire si vous avez une chaîne qui représente une date et une heure mais qui n'est pas au format ISO 8601?
Heureusement, Python datetime
fournit une méthode appelée .strptime ()
pour gérer cette situation. Cette méthode utilise un spécial mini-langue pour indiquer à Python quelles parties de la chaîne sont associées au datetime
les attributs.
Pour construire un datetime
à partir d'une chaîne en utilisant .strptime ()
, vous devez dire à Python ce que chacune des parties de la chaîne représente à l'aide des codes de mise en forme du mini-langage. Vous pouvez essayer cet exemple pour voir comment .strptime ()
travaux:
1 >>> date_string = "31-01-2020 14:45:37"
2 >>> format_string = "% m-%ré-% Y% H:% M:% S "
Sur ligne 1, tu crées date_string
, qui représente la date et l'heure du 31 janvier 2020 à 14 h 45 min 37 s. Sur ligne 2, tu crées format_string
, qui utilise le mini-langage pour spécifier comment les parties de date_string
sera transformé en datetime
les attributs.
Dans format_string
, vous incluez plusieurs codes de mise en forme et tous les tirets (-
), deux points (:
) et les espaces tels qu'ils apparaissent dans date_string
. Pour traiter la date et l'heure dans date_string
, vous incluez les codes de mise en forme suivants:
Composant | Code | Valeur |
---|---|---|
Année (sous forme d'entier à quatre chiffres) | % Y |
2020 |
Mois (sous forme décimale complétée par zéro) | % m |
01 |
Date (sous forme décimale complétée par zéro) | %ré |
31 |
Heure (sous forme décimale à zéro avec horloge de 24 heures) | % H |
14 |
Minute (sous forme décimale complétée par zéro) | % M |
45 |
Deuxième (sous forme décimale complétée par zéro) | % S |
37 |
Une liste complète de toutes les options du mini-langage n'entre pas dans le cadre de ce didacticiel, mais vous pouvez trouver plusieurs bonnes références sur le Web, y compris dans la documentation de Python et sur un site Web appelé strftime.org.
Maintenant que date_string
et format_string
sont définis, vous pouvez les utiliser pour créer un datetime
exemple. Voici un exemple de la façon dont .strptime ()
travaux:
3 >>> de datetime importation datetime
4 >>> datetime.strptime(date_string, format_string)
5 datetime.datetime (2020, 1, 31, 14, 45, 37)
Dans ce code, vous importez datetime
sur ligne 3 et utilise datetime.strptime ()
avec date_string
et format_string
sur ligne 4. Finalement, ligne 5 affiche les valeurs des attributs dans le datetime
instance créée par .strptime ()
. Vous pouvez voir qu'ils correspondent aux valeurs indiquées dans le tableau ci-dessus.
Remarque: Il existe des moyens plus avancés de créer datetime
mais elles impliquent l'utilisation de bibliothèques tierces qui doivent être installées. Une bibliothèque particulièrement soignée s'appelle datparser
, qui vous permet de fournir des entrées de chaîne en langage naturel. L'entrée est même prise en charge dans plusieurs langues:
1 >>> importation datparser
2 >>> datparser.analyser("hier")
3 datetime.datetime (2020, 3, 13, 14, 39, 1, 350918)
4 >>> datparser.analyser("morgen")
5 datetime.datetime (2020, 3, 15, 14, 39, 7, 314754)
Dans ce code, vous utilisez datparser
créer deux datetime
instances en passant deux représentations différentes de chaîne de temps. Sur ligne 1, vous importez datparser
. Puis, le ligne 2, tu utilises .parse ()
avec l'argument "hier"
créer un datetime
par exemple vingt-quatre heures dans le passé. Au moment de la rédaction, c'était le 13 mars 2020 à 14 h 39.
Sur ligne 3, tu utilises .parse ()
avec l'argument "morgen"
. Morgen est le mot allemand pour demain, donc datparser
crée un datetime
par exemple vingt-quatre heures dans le futur. Au moment de la rédaction, c'était le 15 mars à 14 h 39.
Démarrage de votre compte à rebours PyCon
Maintenant, vous avez suffisamment d'informations pour commencer à travailler sur un compte à rebours pour PyCon US l'année prochaine! PyCon US 2021 débutera le 12 mai 2021 à Pittsburgh, en Pennsylvanie. L'événement 2020 ayant été annulé, de nombreux Pythonistes sont très excités pour le rassemblement de l'année prochaine. C'est un excellent moyen de savoir combien de temps vous devrez attendre et d'augmenter votre datetime
compétences en même temps!
Pour commencer, créez un fichier appelé pyconcd.py
et ajoutez ce code:
# pyconcd.py
de datetime importation datetime
PYCON_DATE = datetime(an=2021, mois=5, journée=12, heure=8)
compte à rebours = PYCON_DATE - datetime.maintenant()
impression(F"Compte à rebours pour PyCon US 2021: compte à rebours")
Dans ce code, vous importez datetime
de datetime
et définir une constante, PYCON_DATE
, qui stocke la date de la prochaine PyCon US. Vous ne vous attendez pas à ce que la date de PyCon change, vous nommez donc la variable en majuscules pour indiquer qu'il s'agit d'une constante.
Ensuite, vous calculez la différence entre datetime.now ()
, qui est l'heure actuelle, et PYCON_DATE
. Faire la différence entre deux datetime
instances renvoie un datetime.timedelta
exemple.
timedelta
les instances représentent le changement de temps entre deux datetime
instances. le delta dans le nom est une référence à la lettre grecque delta, qui est utilisée en science et en ingénierie pour signifier un changement. Vous en apprendrez plus tard sur la façon d'utiliser timedelta
pour des opérations arithmétiques plus générales.
Enfin la sortie imprimée, au 9 avril 2020 à un peu avant 21h30 est:
Compte à rebours pour PyCon US 2021: 397 jours, 10: 35: 32.139350
Seulement 397 jours avant PyCon US 2021! Cette sortie est un peu maladroite. Par conséquent, vous verrez plus tard comment améliorer la mise en forme. Si vous exécutez ce script un autre jour, vous obtiendrez une sortie différente. Si vous exécutez le script après le 12 mai 2021 à 8h00, vous aurez un temps négatif restant!
Travailler avec des fuseaux horaires
Comme vous l'avez vu précédemment, le stockage du fuseau horaire dans lequel une date se produit est un aspect important pour s'assurer que votre code est correct. Python datetime
fournit tzinfo
, qui est une classe de base abstraite qui permet datetime.datetime
et datetime.time
pour inclure des informations de fuseau horaire, y compris une idée de l'heure d'été.
cependant, datetime
ne fournit pas un moyen direct d'interagir avec la base de données de fuseau horaire IANA. Le Python datetime.tzinfo
la documentation recommande d'utiliser un package tiers appelé dateutil
. Vous pouvez installer dateutil
avec pépin
:
$ python -m pip install python-dateutil
Notez que le nom du package que vous installez à partir de PyPI, python-dateutil
, est différent du nom que vous utilisez pour importer le package, qui est juste dateutil
.
En utilisant dateutil
ajouter des fuseaux horaires à Python datetime
Une raison pour laquelle dateutil
est si utile qu'il inclut une interface avec la base de données des fuseaux horaires de l'IANA. Cela vous évite d'affecter des fuseaux horaires à votre datetime
instances. Essayez cet exemple pour voir comment définir un datetime
par exemple pour avoir votre fuseau horaire local:
>>> de dateutil importation tz
>>> de datetime importation datetime
>>> maintenant = datetime.maintenant(tz=tz.tzlocal())
>>> maintenant
datetime.datetime (2020, 1, 26, 0, 55, 3, 372824, tzinfo = tzlocal ())
>>> maintenant.tzname()
«Heure normale de l'Est»
Dans cet exemple, vous importez tz
de dateutil
et datetime
de datetime
. Vous créez ensuite un datetime
instance définie sur l'heure actuelle à l'aide de .maintenant()
.
Vous passez également le tz
mot-clé à .maintenant()
Et mettre tz
égal à tz.tzlocal ()
. Dans dateutil
, tz.tzlocal ()
renvoie une instance concrète de datetime.tzinfo
. Cela signifie qu'il peut représenter toutes les informations de décalage de fuseau horaire et d'heure d'été nécessaires datetime
Besoins.
Vous imprimez également le nom du fuseau horaire en utilisant .tzname ()
, qui imprime «Heure normale de l'Est»
. Ceci est la sortie pour Windows, mais sur macOS ou Linux, votre sortie peut lire 'EST'
si vous êtes dans le fuseau horaire de l'Est américain pendant l'hiver.
Vous pouvez également créer des fuseaux horaires différents du fuseau horaire signalé par votre ordinateur. Pour ce faire, vous utiliserez tz.gettz ()
et passez le nom officiel de l'IANA pour le fuseau horaire qui vous intéresse. Voici un exemple d'utilisation tz.gettz ()
:
>>> de dateutil importation tz
>>> de datetime importation datetime
>>> London_tz = tz.gettz("Europe / Londres")
>>> maintenant = datetime.maintenant(tz=London_tz)
>>> maintenant
datetime.datetime (2020, 1, 26, 6, 14, 53, 513460, tzinfo = tzfile ('GB-Eire'))
>>> maintenant.tzname()
'GMT'
Dans cet exemple, vous utilisez tz.gettz ()
pour récupérer les informations de fuseau horaire pour Londres, Royaume-Uni et les stocker dans London_tz
. Vous récupérez ensuite l'heure actuelle en définissant le fuseau horaire sur London_tz
.
Sous Windows, cela donne tzinfo
attribuer la valeur tzfile («GB-Eire»)
. Sous macOS ou Linux, le tzinfo
l'attribut ressemblera à quelque chose tzfile ('/ usr / share / zoneinfo / Europe / London)
, mais cela peut être légèrement différent selon l'endroit dateutil
extrait les données de fuseau horaire.
Vous utilisez également tzname ()
pour imprimer le nom du fuseau horaire, qui est maintenant 'GMT'
, ce qui signifie Greenwich Mean Time. Cette sortie est la même sous Windows, macOS et Linux.
Dans une section précédente, vous avez appris que vous ne devriez pas utiliser .utcnow ()
créer un datetime
par exemple à l'heure UTC actuelle. Vous savez maintenant utiliser dateutil.tz
pour fournir un fuseau horaire au datetime
exemple. Voici un exemple modifié à partir de la recommandation de la documentation Python:
>>> de dateutil importation tz
>>> de datetime importation datetime
>>> datetime.maintenant(tz=tz.UTC)
datetime.datetime (2020, 3, 14, 19, 1, 20, 228415, tzinfo = tzutc ())
Dans ce code, vous utilisez tz.UTC
pour définir le fuseau horaire de datetime.now ()
au fuseau horaire UTC. Cette méthode est recommandée par rapport à l'utilisation utcnow ()
parce que utcnow ()
renvoie un naïve datetime
par exemple, alors que la méthode illustrée ici renvoie un conscient datetime
exemple.
Ensuite, vous ferez un petit détour pour en savoir plus sur naïve contre conscient datetime
instances. Si vous savez déjà tout à ce sujet, vous pouvez passer à l'étape suivante pour améliorer votre compte à rebours PyCon avec les informations de fuseau horaire.
Comparaison de Python Naive et Aware datetime
Instances
Python datetime
les instances prennent en charge deux types d'opérations, naïves et conscientes. La différence fondamentale entre eux est que les instances naïves ne contiennent pas d'informations de fuseau horaire, contrairement aux instances conscientes. Plus formellement, pour citer la documentation Python:
Un objet conscient représente un moment précis dans le temps qui n'est pas ouvert à l'interprétation. Un objet naïf ne contient pas suffisamment d'informations pour se localiser sans ambiguïté par rapport à d'autres objets de date / heure. (La source)
Il s'agit d'une distinction importante pour travailler avec Python datetime
. Une conscient datetime
exemple peut se comparer sans ambiguïté à d'autres conscients datetime
instances et renverra toujours l'intervalle de temps correct lorsqu'il est utilisé dans des opérations arithmétiques.
Naïve datetime
les instances, en revanche, peuvent être ambiguës. Un exemple de cette ambiguïté concerne l'heure d'été. Les zones qui pratiquent l'heure d'été tournent les horloges d'une heure au printemps et d'une heure en arrière à l'automne. Cela se produit généralement à 2 h 00, heure locale. Au printemps, l'heure de 2h00 à 2h59 n'arrive jamais, et à l'automne, l'heure de 1 h 00 à 1 h 59 se produit deux fois!
En pratique, ce qui se passe, c'est que le décalage par rapport à l'UTC dans ces fuseaux horaires change tout au long de l'année. L'IANA suit ces changements et les catalogue dans les différents fichiers de base de données que votre ordinateur a installés. Utiliser une bibliothèque comme dateutil
, qui utilise la base de données IANA sous le capot, est un excellent moyen de s'assurer que votre code gère correctement l'arithmétique avec le temps.
Remarque: En Python, la différence entre naïf et conscient datetime
instances est déterminée par la tzinfo
attribut. Un conscient datetime
l'instance a le tzinfo
attribut égal à une sous-classe du datetime.tzinfo
classe de base abstraite.
Python fournit une implémentation concrète de tzinfo
appelé fuseau horaire
. cependant, fuseau horaire
se limite à exprimer des décalages fixes d'UTC qui ne peuvent pas changer tout au long de l'année. Par conséquent, cela n'est pas très utile lorsque vous devez prendre en compte des modifications telles que l'heure d'été.
dateutil
fournit également plusieurs implémentations concrètes de tzinfo
dans le tz
module que vous avez utilisé précédemment. Vous pouvez consulter le dateutil.tz
documentation pour plus d'informations.
Cela ne signifie pas que vous devez toujours utiliser datetime
instances. Mais les instances conscientes sont cruciales si vous comparez des temps entre eux, surtout si vous comparez des temps dans différentes parties du monde.
Améliorer votre compte à rebours PyCon
Maintenant que vous savez comment ajouter des informations de fuseau horaire à un Python datetime
par exemple, vous pouvez améliorer votre code de compte à rebours PyCon. Plus tôt, vous avez utilisé la norme datetime
constructeur pour passer l'année, le mois, le jour et l'heure de démarrage de PyCon. Vous pouvez mettre à jour votre code pour utiliser le dateutil.parser
module, qui fournit une interface plus naturelle pour la création datetime
instances:
# pyconcd.py
de dateutil importation analyseur, tz
de datetime importation datetime
PYCON_DATE = analyseur.analyser("12 mai 2021 8 h 00")
PYCON_DATE = PYCON_DATE.remplacer(tzinfo=tz.gettz("Amérique / New_York"))
maintenant = datetime.maintenant(tz=tz.tzlocal())
compte à rebours = PYCON_DATE - maintenant
impression(F"Compte à rebours pour PyCon US 2021: compte à rebours")
Dans ce code, vous importez analyseur
et tz
de dateutil
et datetime
de datetime
. Ensuite, vous utilisez parser.parse ()
pour lire la date du prochain PyCon US à partir d'une chaîne. C'est beaucoup plus lisible que la plaine datetime
constructeur.
parser.parse ()
renvoie un naïf datetime
par exemple, vous utilisez donc .remplacer()
pour changer le tzinfo
à la Amérique / New_York
fuseau horaire. PyCon US 2021 aura lieu à Pittsburgh, en Pennsylvanie, dans le fuseau horaire de l'Est américain. Le nom canonique de ce fuseau horaire est Amérique / New_York
puisque New York est la plus grande ville du fuseau horaire.
PYCON_DATE
est conscient datetime
par exemple avec le fuseau horaire défini sur l'heure de l'Est américain. Le 12 mai étant après l'entrée en vigueur de l'heure d'été, le nom du fuseau horaire est 'EDT'
, ou «Heure avancée de l'Est»
.
Ensuite, vous créez maintenant
pour représenter l'instant actuel et lui donner votre fuseau horaire local. Enfin, vous trouvez le timedelta
entre PYCON_DATE
et maintenant
et imprimez le résultat. Si vous vous trouvez dans une région qui n'ajuste pas les horloges pour l'heure d'été, vous pouvez voir le nombre d'heures restantes jusqu'à ce que PyCon change d'une heure.
Faire de l'arithmétique avec Python datetime
Python datetime
les instances prennent en charge plusieurs types d'arithmétique. Comme vous l'avez vu précédemment, cela repose sur l'utilisation timedelta
instances pour représenter des intervalles de temps. timedelta
est très utile car il est intégré à la bibliothèque standard Python. Voici un exemple de la façon de travailler avec timedelta
:
>>> de datetime importation datetime, timedelta
>>> maintenant = datetime.maintenant()
>>> maintenant
datetime.datetime (2020, 1, 26, 9, 37, 46, 380905)
>>> demain = timedelta(journées= +1)
>>> maintenant + demain
datetime.datetime (2020, 1, 27, 9, 37, 46, 380905)
Dans ce code, vous créez maintenant
, qui stocke l'heure actuelle, et demain
, qui est un timedelta
de +1
journées. Ensuite, vous ajoutez maintenant
et demain
pour produire un datetime
par exemple un jour dans le futur. Notez que travailler avec naïf datetime
comme vous êtes ici, signifie que le journée
attribut de datetime
incrémente d'une unité et ne tient pas compte des intervalles de temps répétés ou ignorés.
timedelta
les instances prennent également en charge les valeurs négatives en entrée des arguments:
>>> hier = timedelta(journées= -1)
>>> maintenant + hier
datetime.datetime (2020, 1, 25, 9, 37, 46, 380905)
Dans cet exemple, vous fournissez -1
comme entrée timedelta
, donc quand vous ajoutez maintenant
et hier
, le résultat est une diminution de un journées
attribut.
timedelta
les instances prennent en charge l'addition et la soustraction ainsi que les entiers positifs et négatifs pour tous les arguments. Vous pouvez même fournir un mélange d'arguments positifs et négatifs. Par exemple, vous souhaiterez peut-être ajouter trois jours et soustraire quatre heures:
>>> delta = timedelta(journées= +3, heures= -4)
>>> maintenant + delta
datetime.datetime (2020, 1, 29, 5, 37, 46, 380905)
Dans cet exemple, vous ajoutez trois jours et soustrayez quatre heures, de sorte que le nouveau datetime
est au 29 janvier à 05h37. timedelta
est très utile de cette façon, mais il est quelque peu limité car il ne peut pas ajouter ou soustraire des intervalles supérieurs à une journée, comme un mois ou une année. Heureusement, dateutil
fournit un remplacement plus puissant appelé relativedelta
.
La syntaxe de base de relativedelta
est très similaire à timedelta
. Vous pouvez fournir des arguments de mots clés qui produisent des modifications d'un nombre quelconque d'années, de mois, de jours, d'heures, de secondes ou de microsecondes. Vous pouvez reproduire le premier timedelta
exemple avec ce code:
>>> de dateutil.relativedelta importation relativedelta
>>> demain = relativedelta(journées= +1)
>>> maintenant + demain
datetime.datetime (2020, 1, 27, 9, 37, 46, 380905)
Dans cet exemple, vous utilisez relativedelta
au lieu de timedelta
pour trouver le datetime
correspondant à demain. Vous pouvez maintenant essayer d'ajouter cinq ans, un mois et trois jours maintenant
en soustrayant quatre heures et trente minutes:
>>> delta = relativedelta(années= +5, mois= +1, journées= +3, heures= -4, minutes= -30)
>>> maintenant + delta
datetime.datetime (2025, 3, 1, 5, 7, 46, 380905)
Notez dans cet exemple que la date se termine le 1er mars 2025. En effet, l'ajout de trois jours à maintenant
serait le 29 janvier, et l'ajout d'un mois serait le 29 février, qui n'existe que dans une année bissextile. Puisque 2025 n'est pas une année bissextile, la date est reportée au mois suivant.
Vous pouvez aussi utiliser relativedelta
calculer la différence entre deux datetime
instances. Plus tôt, vous avez utilisé l'opérateur de soustraction pour trouver la différence entre deux Python datetime
instances, PYCON_DATE
et maintenant
. Avec relativedelta
, au lieu d'utiliser l'opérateur de soustraction, vous devez passer les deux datetime
instances comme arguments:
>>> maintenant
datetime.datetime (2020, 1, 26, 9, 37, 46, 380905)
>>> demain = datetime(2020, 1, 27, 9, 37, 46, 380905)
>>> relativedelta(maintenant, demain)
relativedelta (jours = -1)
Dans cet exemple, vous créez un nouveau datetime
exemple pour demain
en incrémentant le journées
champ par un. Ensuite, vous utilisez relativedelta
et passer maintenant
et demain
comme les deux arguments. dateutil
prend ensuite la différence entre ces deux datetime
instances et renvoie le résultat sous la forme relativedelta
exemple. Dans ce cas, la différence est -1
jours, depuis maintenant
arrive avant demain
.
dateutil.relativedelta
les objets ont d'innombrables autres utilisations. Vous pouvez les utiliser pour trouver des informations de calendrier complexes, telles que l'année suivante au cours de laquelle le 13 octobre tombe un vendredi ou quelle sera la date du dernier vendredi du mois en cours. Vous pouvez même les utiliser pour remplacer les attributs d'un datetime
instance et créer, par exemple, un datetime
une semaine dans le futur à 10h00. Vous pouvez tout lire sur ces autres utilisations dans le dateutil
Documentation.
Fin de votre compte à rebours PyCon
Vous avez maintenant suffisamment d'outils dans votre ceinture pour terminer votre compte à rebours PyCon 2021 et fournir une interface agréable à utiliser également. Dans cette section, vous allez utiliser relativedelta
pour calculer le temps restant jusqu'à PyCon, développer une fonction pour imprimer le temps restant dans un format sympa, et montrer la date de PyCon à l'utilisateur.
En utilisant relativedelta
dans votre compte à rebours PyCon
Tout d'abord, remplacez l'opérateur de soustraction simple par relativedelta
. Avec l'opérateur de soustraction, votre timedelta
l'objet ne pouvait pas compter des intervalles de temps supérieurs à un jour. cependant, relativedelta
vous permet d'afficher les années, les mois et les jours restants:
1 # pyconcd.py
2
3 de dateutil importation analyseur, tz
4 de dateutil.relativedelta importation relativedelta
5 de datetime importation datetime
6
7 PYCON_DATE = analyseur.analyser("12 mai 2021 8 h 00")
8 PYCON_DATE = PYCON_DATE.remplacer(tzinfo=tz.gettz("Amérique / New_York"))
9 maintenant = datetime.maintenant(tz=tz.tzlocal())
dix
11 compte à rebours = relativedelta(PYCON_DATE, maintenant)
12 impression(F"Compte à rebours pour PyCon US 2021: compte à rebours")
La seule modification que vous avez apportée à ce code a été de remplacer ligne 11 avec compte à rebours = relativedelta (PYCON_DATE, maintenant)
. La sortie de ce script devrait vous indiquer que PyCon US 2021 se produira dans environ un an et un mois, selon le moment où vous exécuterez le script.
Cependant, cette sortie n'est pas très jolie car elle ressemble à la signature de relativedelta ()
. Vous pouvez créer une sortie plus jolie en remplaçant ligne 11 dans le code précédent avec le code ci-dessous:
11 def time_amount(time_unit: str, compte à rebours: relativedelta) -> str:
12 t = getattr(compte à rebours, time_unit)
13 revenir F"t time_unit" si t ! = 0 autre ""
14
15 compte à rebours = relativedelta(PYCON_DATE, maintenant)
16 unités_heure = [[[["années", "mois", "journées", "heures", "minutes", "secondes"]
17 production = (t pour tu dans unités_heure si (t := time_amount(tu, compte à rebours)))
18 impression("Compte à rebours pour PyCon US 2021:", ",".joindre(production))
Ce code nécessite Python 3.8 car il utilise le nouveau opérateur de morse. Vous pouvez faire fonctionner ce script sur les anciennes versions de Python en utilisant un traditionnel pour
boucle à la place de ligne 17.
Dans ce code, vous définissez time_amount ()
, qui prend deux arguments, l'unité de temps et le relativedelta
instance à partir de laquelle les unités de temps doivent être récupérées. Si la durée n'est pas égale à zéro, alors time_amount ()
renvoie une chaîne avec la quantité de temps et l'unité de temps. Sinon, il renvoie une chaîne vide.
Tu utilises time_amount()
in the comprehension on line 17. That line creates a generator storing the non-empty strings returned from time_amount()
. It uses the walrus operator to assign the return value of time_amount()
à t
and includes t
only if it is Vrai
.
Finally, line 18 prints the final output using .join()
on the generator. Next, you’ll take a look at including the PyCon date in the output from your script.
Showing the PyCon Date in Your PyCon Countdown
Earlier, you learned about creating datetime
instances using .strptime()
. This method uses a special mini-language within Python to specify how the date string is formatted.
Python datetime
has an additional method called .strftime()
that allows you to format a datetime
instance to a string. In a sense, it’s the reverse operation of parsing using .strptime()
. You can differentiate between the two methods by remembering that the p
in .strptime()
stands for parse, et le F
in .strftime()
stands for format.
In your PyCon countdown, you can use .strftime()
to print output to let the user know the date on which PyCon US will start. Remember, you can find the formatting codes that you want to use on strftime.org. Now add this code on line 18 of your PyCon countdown script:
18 pycon_date_str = PYCON_DATE.strftime("%A, %B %d, %Y at %H:%M %p %Z")
19 impression(F"PyCon US 2021 will start on:", pycon_date_str)
20 impression("Countdown to PyCon US 2021:", ",".joindre(output))
In this code, line 18 uses .strftime()
to create a string representing the starting date of PyCon US 2021. The output includes the weekday, month, day, year, hour, minute, AM or PM, and time zone:
Wednesday, May 12, 2021 at 08:00 AM EDT
Sur line 19, you print this string for the user to see with some explanatory text. The last line prints the amount of time remaining until the PyCon start date. Next, you’ll finish your script to make it easier for other people to reuse.
Finalizing Your PyCon Countdown
The final step that you’ll want take is to follow Python best practices and put the code that produces output into a main()
function. You can check out the full, final code after applying all these changes:
1 # pyconcd.py
2
3 de dateutil importation parser, tz
4 de dateutil.relativedelta importation relativedelta
5 de datetime importation datetime
6
7 PYCON_DATE = parser.parse("May 12, 2021 8:00 AM")
8 PYCON_DATE = PYCON_DATE.remplacer(tzinfo=tz.gettz("America/New_York"))
9
dix def time_amount(time_unit: str, countdown: relativedelta) -> str:
11 t = getattr(countdown, time_unit)
12 revenir F"t time_unit" if t != 0 autre ""
13
14 def principale():
15 maintenant = datetime.maintenant(tz=tz.tzlocal())
16 countdown = relativedelta(PYCON_DATE, maintenant)
17 time_units = [[[["years", "months", "days", "hours", "minutes", "seconds"]
18 output = (t pour tu in time_units if (t := time_amount(tu, countdown)))
19 pycon_date_str = PYCON_DATE.strftime("%A, %B %d, %Y at %H:%M %p %Z")
20 impression(F"PyCon US 2021 will start on:", pycon_date_str)
21 impression("Countdown to PyCon US 2021:", ",".joindre(output))
22
23 if __Nom__ == "__main__":
24 principale()
In this code, you move print()
and the code used for the generator into main()
. Sur line 23, you use the guard clause to make sure that main()
only runs when this file is executed as a script. This allows other people to import your code and reuse PYCON_DATE
, for instance, if they’d like.
Now you can modify this script as much as you want. One neat thing to do might be to allow the user to change the time zone associated with maintenant
by passing a command-line argument. You could also change the PYCON_DATE
to something closer to home, say PyCon Africa or EuroPython.
To get even more excited about PyCon, check out Real Python at PyCon US 2019 and How to Get the Most Out of PyCon!
Alternatives to Python datetime
et dateutil
Python datetime
et dateutil
are a powerful combination of libraries when you’re working with dates and times. dateutil
is even recommended in the Python documentation. However, there are many other libraries that you can use to work with dates and times in Python. Some of these rely on datetime
et dateutil
, while others are completely independent replacements:
- pytz provides time zone information similar to
dateutil
. It uses a somewhat different interface than the standarddatetime.tzinfo
, so be aware of the potential problems if you decide to use it. - Arrow provides a drop-in replacement for
datetime
. It’s inspired bymoment.js
, so if you’re coming from web development, then this might be a more familiar interface. - Pendulum provides another drop-in replacement for
datetime
. It includes a time zone interface and an improvedtimedelta
implementation. - Maya provides a similar interface as
datetime
. It relies on Pendulum for parts of the parsing library. - dateparser provides an interface to generate
datetime
instances from human-readable text. It’s flexible and supports many languages.
In addition, if you work heavily with NumPy, Pandas, or other data science packages, then there are a few options that might be useful to you:
- NumPy provides a similar API to the built-in Python
datetime
library, but the NumPy version can be used in arrays. - Pandas provides support for time-series data in DataFrames, usually sequential values of time-based events, by using the NumPy
datetime
module. - cftime provides support for calendars other than the proleptic Gregorian calendar as well as other time units conforming to the Climate and Forecasting (CF) conventions. It’s used by the
xarray
package to provide time-series support.
Lectures complémentaires
Since programming with time can be so complicated, there are many resources on the web to help you learn more about it. Fortunately, this is a problem that many people who work in every programming language have thought about, so you can usually find information or tools to help with any problem you may have. Here’s a selected list of articles and videos that I found helpful in writing this tutorial:
In addition, Paul Ganssle is a core contributor to CPython and the current maintainer of dateutil
. His articles and videos are a great resource for Python users:
Conclusion
In this tutorial, you learned about programming with dates and times and why it often leads to errors and confusion. You also learned about the Python datetime
et dateutil
modules as well as how to work with time zones in your code.
Now you can:
- Store dates in a good, future-proof format in your programs
- Créer Python
datetime
instances with formatted strings - Ajouter time zone information to
datetime
instances withdateutil
- Effectuer arithmetic operations with
datetime
instances usingrelativedelta
In the end, you created a script that counts down the time remaining until the next PyCon US so you can get excited for the biggest Python gathering around. Dates and times can be tricky, but with these Python tools in your arsenal, you’re ready to tackle the toughest problems!
[ad_2]