---
title: Types supplémentaires
author: Steve Kossouho
---

# Types supplémentaires

----

## `datetime` : Des moments dans le temps

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, un type pour stocker des moments dans le temps, nommé `datetime`,
est fourni.

```python {.numberLines}
from datetime import datetime

now = datetime.now()  # l'instant actuel
midnight = datetime(2021, 1, 31)  # 31 janvier 2021 à minuit
noon = datetime(2021, 1, 31, hour=12)  # 31 janvier 2021 à 12h00

print(now)
print(midnight)
print(noon)
```

----

Les objets de type `datetime`{.python} sont exploitables grâce à plusieurs
méthodes et attributs :

```python {.numberLines}
from datetime import datetime

now = datetime.now()
print(now.year)  # Année 
print(now.month)  # Mois (int)
print(now.day)  # Jour (int)
print(now.hour)  # Heure (int)
print(now.weekday())  # Jour de la semaine (int)
print(now.date())  # objet qui représente une journée
print(now.timestamp())  # Timestamp Unix (float)
```

----

## `date` : Une journée

Le type `date` du module `datetime` permet de représenter des jours,
sans notion d'heure.

```python {.numberLines}
from datetime import date

event_1 = date(1944, 6, 6)  # 6 juin 1944
event_2 = date(1986, 4, 26)  # 26 avril 1986

print(event_1.year)
print(event_1.month)
print(event_1.day)
```

----

## `timedelta` : Intervalles de temps

Un troisième type de données, `timedelta`, permet de représenter des durées.
Vous pouvez obtenir des objets de ce type de deux façons :

- Soit en calculant la différence entre deux `datetime` ou `date`;
- Soit en créant explicitement un objet de ce type;
- Soit en ajoutant des objets de ce type.


```python {.numberLines}
from datetime import timedelta, datetime, date

event_1 = date(2003, 6, 11)  # 11 juin 2003
event_2 = date(2003, 9, 27)  # 27 septembre 2003
elapsed = event_2 - event_1  # 108 jours

custom_duration = timedelta(weeks=4, days=2, hours=5, minutes=10)
double_duration = custom_duration * 2.0
event_end = event_1 + custom_duration
```

----

Les objets `timedelta` possèdent peu d'attributs et de méthodes. 
Nous pouvons récupérer d'un tel objet les informations suivantes :

- `timedelta.days`
- `timedelta.seconds`
- `timedelta.microseconds`.

Ces informations additionnées donnent la durée complète.

Cette dernière peut être obtenue en secondes grâce à la méthode `total_seconds()` :

```python {.numberLines}
from datetime import timedelta

interval = timedelta(weeks=4.3, hours=14, minutes=31, seconds=53.234_567)
print(f"Nombre de jours : {interval.days}")
print(f"Secondes restantes : {interval.seconds}")
print(f"Microsecondes restantes : {interval.microseconds}")
print(f"Durée totale (s) : {interval.total_seconds():.3f}")
```

----

## Récupérer un `datetime` depuis un [timestamp]{.naming}

Un [timestamp]{.naming} est un instant exprimé sous la forme d'un nombre entier (ou flottant).
Dans la plupart des environnements de programmation, un timestamp s'exprime en nombre de secondes 
écoulées depuis le `1er janvier 1970 à 00:00:00 UTC`. On appelle ce moment l'[epoch Unix]{.naming}.

On peut calculer un objet `datetime`{.python} depuis un timestamp, ou inversément, un timestamp depuis un objet `datetime`{.python}.

```python {.numberLines}
from datetime import datetime

stamp_1 = 1577836800.24  # 1 janvier 2020 à 01h00
event_1 = datetime.fromtimestamp(stamp_1)  # 1 janvier 2020 à 01h00
event_2 = datetime(1996, 4, 1)  # I Got the Vibration
stamp_2 = event_2.timestamp()  # 828309600
print(f"La date du timestamp 1 est : {event_1}")
print(f"Le timestamp de la date 2 est : {stamp_2}")
```

----

## Générer une chaîne depuis une date

Pour convertir des informations d'un objet `date` ou `datetime` et générer une chaîne (ou vice-versa)
vous devez vous référer en premier lieu à une ressource de référence :

[Table de référence pour le formatage de dates](https://docs.python.org/fr/3/library/datetime.html#strftime-and-strptime-format-codes)

Ce tableau de référence reprend les spécifications des mêmes fonctionnalités telles que fournies par la
bibliothèque standard du C.

```python {.numberLines}
from datetime import datetime

event = datetime.now()
print(event.strftime("%d/%m/%Y %H:%M et %S secondes."))
print(f"{event:%d/%m/%Y %H:%M et %S secondes}")  # via des f-strings
```

----

### Éléments de date localisés dans la langue système

Par défaut, Python n'utilise pas la langue configurée sur votre système d'exploitation,
mais l'anglais pour générer des chaînes de caractères depuis vos objets `datetime`;

Pour demander à Python d'utiliser votre configuration système, utilisez une chaîne vide
pour définir le code de langue à utiliser.

```python {.numberLines}
from datetime import datetime
import locale

locale.setlocale(locale.LC_ALL, "")  # utilise les paramètres de langue de l'utilisateur
event_1 = datetime.now()
print(f"{event_1:%A %d %B %Y}")
```

[Documentation sur setlocale](https://docs.python.org/fr/3/library/locale.html)

----

## Obtenir un objet `datetime` depuis une chaîne

Ici, il s'agit de comprendre la structure d'une chaîne de caractères contenant 
une date et en déduire un objet `datetime`.

```python {.numberLines}
from datetime import datetime

text = "31/10/1991 15:17"
# La méthode `strptime` est utilisée (string parse time)
moment = datetime.strptime(text, "%d/%m/%Y %H:%M")
print(moment)
```

----

## Extra : Fuseaux horaires

Par défaut, les objets de date que vous confectionnez sont dits [naïfs]{.naming}, 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.

----

### Fuseaux horaires avec Python 3.9+

Depuis la version 3.9, Python propose un module `zoneinfo`, qui offre un type `ZoneInfo`
applicable à des objets `datetime` :

```python {.numberLines}
from datetime import datetime, UTC
from zoneinfo import ZoneInfo

moment_madrid = datetime(1975, 3, 1, hour=13, tzinfo=ZoneInfo("Europe/Madrid"))
moment_utc = datetime(1966, 10, 5, tzinfo=UTC)
```

----

## Bonus : Bibliothèques tierces pour les dates

L'écosystème Python propose des bibliothèques simplifiant l'usage des dates :

- [Arrow](https://arrow.readthedocs.io/en/latest/) : Better dates and times for Python
- [Pendulum](https://pendulum.eustace.io/) : Python datetimes made easy
