Initial commit
This commit is contained in:
195
documentation/06-extra-types.md
Normal file
195
documentation/06-extra-types.md
Normal file
@ -0,0 +1,195 @@
|
||||
---
|
||||
title: Types supplémentaires
|
||||
author: Steve Kossouho
|
||||
---
|
||||
|
||||
# Types supplémentaires
|
||||
|
||||
----
|
||||
|
||||
## Un type pour les dates et heures
|
||||
|
||||
La bibliothèque standard nous offre plusieurs types de données pour gérer des moments dans le temps, avec le module `datetime`. Dans ce module, le type pour les dates avec heure s'appelle aussi `datetime`.
|
||||
|
||||
```{.python .numberLines}
|
||||
from datetime import datetime
|
||||
|
||||
now = datetime.now()
|
||||
then = datetime(2021, 1, 31) # arguments positionnels
|
||||
then2 = datetime(2021, 1, 31, hour=12) # arguments par défaut
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
Les objets de ce type offrent un accès à plusieurs attributs, pour récupérer le jour, le mois, l'heure etc.
|
||||
|
||||
```{.python .numberLines}
|
||||
from datetime import datetime
|
||||
|
||||
now = datetime.now()
|
||||
print(now.day, now.date()) # affiche le jour du mois, et la date sans l'heure
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
## Opérations arithmétiques entre dates et intervalles de temps
|
||||
|
||||
Le module `datetime` propose un type qui représente un intervalle de temps, nommé `timedelta`.
|
||||
C'est ce que l'on obtient quand on soustrait deux dates (le temps écoulé entre les deux).
|
||||
Mais on peut aussi créer des objets `timedelta`{.python} et les ajouter (ou soustraire) à des dates.
|
||||
|
||||
```{.python .numberLines}
|
||||
from datetime import timedelta, datetime
|
||||
|
||||
interval = timedelta(hours=15)
|
||||
now = datetime.now()
|
||||
then = datetime(2000, 1, 1)
|
||||
interval2 = now - then
|
||||
the_future = now + interval # dans 15 heures
|
||||
print(interval2, the_future)
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
Les objets d'intervalle de temps donnent accès à peu d'attributs. Nous avons uniquement accès aux jours, secondes et microsecondes.
|
||||
On préférera utiliser le résultats renvoyés par la méthode `total_seconds()` comme base pour nos propres conversions d'ordres de grandeur.
|
||||
|
||||
```{.python .numberLines}
|
||||
from datetime import timedelta
|
||||
|
||||
interval = timedelta(hours=14, minutes=31, seconds=53)
|
||||
print(interval.days, interval.seconds, interval.microseconds)
|
||||
print(interval.total_seconds())
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
## Récupérer une date depuis un timestamp
|
||||
|
||||
Un [timestamp]{.naming} est une date exprimée sous la forme d'un nombre entier (ou flottant).
|
||||
En général, un timestamp en programmation est le nombre de secondes depuis le
|
||||
1er janvier 1970 à 00:00:00 UTC. On appelle ce moment l'epoch Unix.
|
||||
|
||||
On peut calculer un objet `datetime`{.python} depuis un timestamp, ou un timestamp depuis un objet `datetime`{.python}.
|
||||
|
||||
```python {.numberLines}
|
||||
from datetime import datetime
|
||||
|
||||
timestamp = 1577836800
|
||||
as_datetime = datetime.fromtimestamp(timestamp)
|
||||
print(as_datetime)
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
|
||||
## Convertir une date en chaîne
|
||||
|
||||
Pour convertir une date vers une chaîne, ou convertir une chaîne vers un objet de date, consultez toujours la même ressource :
|
||||
|
||||
[Table de référence pour le format de dates](https://docs.python.org/fr/3/library/datetime.html#strftime-and-strptime-format-codes)
|
||||
|
||||
----
|
||||
|
||||
### Éléments de date localisés dans la langue système
|
||||
|
||||
Pour une raison inconnue, probablement un bug sous certaines distributions Linux, Python n'utilise pas la langue configurée sur votre système,
|
||||
et vous voyez un formatage tel que `Sunday` s'afficher au lieu de `Dimanche`.
|
||||
Pas de panique, il existe une solution pour forcer Python à utiliser la langue que vous désirez.
|
||||
|
||||
|
||||
```{.python .numberLines}
|
||||
import locale
|
||||
|
||||
locale.setlocale(locale.LC_ALL, "") # utilise les paramètres de langue de l'utilisateur
|
||||
```
|
||||
|
||||
[Documentation sur setlocale](https://docs.python.org/fr/3/library/locale.html)
|
||||
|
||||
----
|
||||
|
||||
Pour convertir un objet `datetime` vers une chaîne, grâce à la table de référence, c'est simple :
|
||||
|
||||
```{.python .numberLines}
|
||||
from datetime import datetime
|
||||
|
||||
now = datetime.now()
|
||||
text = now.strftime("%d/%m/%Y %H:%M et %S secondes.")
|
||||
other = f"{now:%d/%m/%Y %H:%M et %S secondes}" # via des f-strings
|
||||
print(text, other)
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
## Convertir une chaîne en date
|
||||
|
||||
Dans l'autre sens, c'est à peine plus compliqué :
|
||||
|
||||
```{.python .numberLines}
|
||||
from datetime import datetime
|
||||
|
||||
text = "24 12 2003 15:17"
|
||||
moment = datetime.strptime(text, "%d %m %Y %H:%M")
|
||||
print(moment)
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
## Bonus : Fuseaux horaires
|
||||
|
||||
Par défaut, les objets de date que vous confectionnez sont dits naïfs, car ils ne contiennent pas d'information de fuseau
|
||||
horaire. Vous pouvez créer ou modifier des objets pour porter ces informations si vous en avez besoin.
|
||||
|
||||
La façon de s'en servir changera selon que vous utilisez Python 3.9 ou une version antérieure.
|
||||
|
||||
----
|
||||
|
||||
### Fuseaux horaires avant Python 3.9
|
||||
|
||||
Avant Python 3.9, il est conseillé d'installer `pytz` et `tzlocal` avec `pip`, puis de définir vos dates ainsi :
|
||||
|
||||
```{.python .numberLines}
|
||||
import pytz
|
||||
from datetime import datetime
|
||||
|
||||
moment = datetime(2013, 4, 16, tzinfo=pytz.timezone("Europe/Paris"))
|
||||
moment2 = datetime(2010, 1, 1)
|
||||
moment2 = moment2.replace(tzinfo=pytz.UTC)
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
Vous pouvez convertir votre date de façon à la représenter dans un autre fuseau horaire :
|
||||
|
||||
```{.python .numberLines}
|
||||
import pytz, tzlocal
|
||||
from datetime import datetime
|
||||
|
||||
moment = datetime(2013, 4, 16, tzinfo=pytz.timezone("America/Chihuahua"))
|
||||
moment2 = moment.astimezone(tzlocal.get_localzone())
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
### Fuseaux horaires avec Python 3.9+
|
||||
|
||||
Python 3.9 ajoute enfin `zoneinfo`, qui couvre presque totalement les larges lacunes de `tzinfo`. (il demeure impossible
|
||||
de connaître le fuseau horaire local)
|
||||
|
||||
```{.python .numberLines}
|
||||
from datetime import datetime
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
moment = datetime(1975, 3, 1, hour=13, tzinfo=ZoneInfo("Europe/Madrid"))
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
## Bonus : Bibliothèques tierces pour les dates
|
||||
|
||||
L'écosystème Python propose de temps en temps des alternatives plus abordables que les
|
||||
outils présents dans la bibliothèque standard. La gestion de dates n'y échappe pas et je peux proposer
|
||||
deux bibliothèques élégantes et simples à comprendre pour Python :
|
||||
|
||||
- [Arrow](https://arrow.readthedocs.io/en/latest/) : Better dates and times for Python
|
||||
- [Pendulum](https://pendulum.eustace.io/) : Python datetimes made easy
|
Reference in New Issue
Block a user