Apprenez à programmer en Python
Last updated on Monday, September 8, 2014
  • 4 semaines
  • Facile

Ce cours est visible gratuitement en ligne.

Paperback available in this course

Ce cours existe en eBook.

Certificate of achievement available at the end this course

Got it!

Le temps

Exprimer un temps en informatique, cela soulève quelques questions. Disposer d'une mesure du temps dans un programme peut avoir des applications variées : connaître la date et l'heure actuelles et faire remonter une erreur, calculer depuis combien de temps le programme a été lancé, gérer des alarmes programmées, faire des tests de performance… et j'en passe !

Il existe plusieurs façons de représenter des temps, que nous allons découvrir maintenant.

Pour bien suivre ce chapitre, vous aurez besoin de maîtriser l'objet : savoir ce qu'est un objet et comment en créer un.

Le module time

Le module time est sans doute le premier à être utilisé quand on souhaite manipuler des temps de façon simple.

Notez que, dans la documentation de la bibliothèque standard, ce module est classé dans la rubrique Generic Operating System Services (c'est-à-dire les services communs aux différents systèmes d'exploitation). Ce n'est pas un hasard : time est un module très proche du système. Cela signifie que certaines fonctions de ce module pourront avoir des résultats différents sur des systèmes différents. Pour ma part, je vais surtout m'attarder sur les fonctionnalités les plus génériques possibles afin de ne perdre personne.

Je vous invite à consulter la documentation de Python sur la bibliothèque standard et sur le module time, pour plus d'informations.

Représenter une date et une heure dans un nombre unique

Comment représenter un temps ? Il existe, naturellement, plusieurs réponses à cette question. Celle que nous allons voir ici est sans doute la moins compréhensible pour un humain, mais la plus adaptée à un ordinateur : on stocke la date et l'heure dans un seul entier.

Comment représenter une date et une heure dans un unique entier ?

L'idée retenue a été de représenter une date et une heure en fonction du nombre de secondes écoulées depuis une date précise. La plupart du temps, cette date est l'Epoch Unix, le 1er janvier 1970 à 00:00:00.

Pourquoi cette date plutôt qu'une autre ?

Il fallait bien choisir une date de début. L'année 1970 a été considérée comme un bon départ, compte tenu de l'essor qu'a pris l'informatique à partir de cette époque. D'autre part, un ordinateur est inévitablement limité quand il traite des entiers ; dans les langages de l'époque, il fallait tenir compte de ce fait tout simple : on ne pouvait pas compter un nombre de secondes trop important. La date de l'Epoch ne pouvait donc pas être trop reculée dans le temps.

Nous allons voir dans un premier temps comment afficher ce fameux nombre de secondes écoulées depuis le 1er janvier 1970 à 00:00:00. On utilise la fonction time du module time.

>>> import time
>>> time.time()
1297642146.562
>>>

Cela fait beaucoup ! D'un autre côté, songez quand même que cela représente le nombre de secondes écoulées depuis plus de quarante ans à présent.

Maintenant, je vous l'accorde, ce nombre n'est pas très compréhensible pour un humain. Par contre, pour un ordinateur, c'est l'idéal : les durées calculées en nombre de secondes sont faciles à additionner, soustraire, multiplier… bref, l'ordinateur se débrouille bien mieux avec ce nombre de secondes, ce timestamp comme on l'appelle généralement.

Faites un petit test : stockez la valeur renvoyée par time.time() dans une première variable, puis quelques secondes plus tard stockez la nouvelle valeur renvoyée par time.time() dans une autre variable. Comparez-les, soustrayez-les, vous verrez que cela se fait tout seul :

>>> debut = time.time()
>>> # On attend quelques secondes avant de taper la commande suivante
... fin = time.time()
>>> print(debut, fin)
1297642195.45 1297642202.27
>>> debut < fin
True
>>> fin - debut # Combien de secondes entre debut et fin ?
6.812000036239624
>>>

Vous pouvez remarquer que la valeur renvoyée par time.time() n'est pas un entier mais bien un flottant. Le temps ainsi donné est plus précis qu'à une seconde près. Pour des calculs de performance, ce n'est en général pas cette fonction que l'on utilise. Mais c'est bien suffisant la plupart du temps.

La date et l'heure de façon plus présentable

Vous allez me dire que c'est bien joli d'avoir tous nos temps réduits à des nombres mais que ce n'est pas très lisible pour nous. Nous allons découvrir tout au long de ce chapitre des moyens d'afficher nos temps de façon plus élégante et d'obtenir les diverses informations relatives à une date et une heure. Je vous propose ici un premier moyen : une sortie sous la forme d'un objet contenant déjà beaucoup d'informations.

Nous allons utiliser la fonction localtime du module time.

time.localtime()

Elle renvoie un objet contenant, dans l'ordre :

  1. tm_year : l'année sous la forme d'un entier ;

  2. tm_mon : le numéro du mois (entre 1 et 12) ;

  3. tm_mday : le numéro du jour du mois (entre 1 et 31, variant d'un mois et d'une année à l'autre) ;

  4. tm_hour : l'heure du jour (entre 0 et 23) ;

  5. tm_min : le nombre de minutes (entre 0 et 59) ;

  6. tm_sec : le nombre de secondes (entre 0 et 61, même si on n'utilisera ici que les valeurs de 0 à 59, c'est bien suffisant) ;

  7. tm_wday : un entier représentant le jour de la semaine (entre 0 et 6, 0 correspond par défaut au lundi) ;

  8. tm_yday : le jour de l'année, entre 1 et 366 ;

  9. tm_isdst : un entier représentant le changement d'heure local.

Comme toujours, si vous voulez en apprendre plus, je vous renvoie à la documentation officielle du module time.

Comme je l'ai dit plus haut, nous allons utiliser la fonction localtime. Elle prend un paramètre optionnel : le timestamp tel que nous l'avons découvert plus haut. Si ce paramètre n'est pas précisé, localtime utilisera automatiquement time.time() et renverra donc la date et l'heure actuelles.

>>> time.localtime()
time.struct_time(tm_year=2011, tm_mon=2, tm_mday=14, tm_hour=3, tm_min=22, tm_sec=7, tm_wday=0, tm_yday=45, tm_isdst=0)
>>> time.localtime(debut)
time.struct_time(tm_year=2011, tm_mon=2, tm_mday=14, tm_hour=1, tm_min=9, tm_sec=55, tm_wday=0, tm_yday=45, tm_isdst=0)
>>> time.localtime(fin)
time.struct_time(tm_year=2011, tm_mon=2, tm_mday=14, tm_hour=1, tm_min=10, tm_sec=2, tm_wday=0, tm_yday=45, tm_isdst=0)
>>>

Pour savoir à quoi correspond chaque attribut de l'objet, je vous renvoie un peu plus haut. Pour l'essentiel, c'est assez clair je pense. Malgré tout, la date et l'heure renvoyées ne sont pas des plus lisibles. L'avantage de les avoir sous cette forme, c'est qu'on peut facilement extraire une information si on a juste besoin, par exemple, de l'année et du numéro du jour.

Récupérer un timestamp depuis une date

Je vais passer plus vite sur cette fonction car, selon toute vraisemblance, vous l'utiliserez moins souvent. L'idée est, à partir d'une structure représentant les date et heure telles que renvoyées par localtime, de récupérer le timestamp correspondant. On utilise pour ce faire la fonction mktime.

>>> print(debut)
1297642195.45
>>> temps = time.localtime(debut)
>>> print(temps)
time.struct_time(tm_year=2011, tm_mon=2, tm_mday=14, tm_hour=1, tm_min=9, tm_sec=55, tm_wday=0, tm_yday=45, tm_isdst=0)
>>> ts_debut = time.mktime(temps)
>>> print(ts_debut)
1297642195.0
>>>

Mettre en pause l'exécution du programme pendant un temps déterminé

C'est également une fonctionnalité intéressante, même si vous n'en voyez sans doute pas l'utilité de prime abord. La fonction qui nous intéresse est sleep et elle prend en paramètre un nombre de secondes qui peut être sous la forme d'un entier ou d'un flottant. Pour vous rendre compte de l'effet, je vous encourage à tester par vous-mêmes :

>>> time.sleep(3.5) # Faire une pause pendant 3,5 secondes
>>>

Comme vous pouvez le voir, Python se met en pause et vous devez attendre 3,5 secondes avant que les trois chevrons s'affichent à nouveau.

Formater un temps

Intéressons nous maintenant à la fonction strftime. Elle permet de formater une date et heure en la représentant dans une chaîne de caractères.

Elle prend deux paramètres :

  • La chaîne de formatage (nous verrons plus bas comment la former).

  • Un temps optionnel tel que le renvoie localtime. Si le temps n'est pas précisé, c'est la date et l'heure courantes qui sont utilisées par défaut.

Pour construire notre chaîne de formatage, nous allons utiliser plusieurs caractères spéciaux. Python va remplacer ces caractères par leur valeur (la valeur du temps passé en second paramètre ou du temps actuel sinon).

Exemple :

time.strftime('%Y')

Voici un tableau récapitulatif des quelques symboles que vous pouvez utiliser dans cette chaîne :

Symbole

Signification

%A

Nom du jour de la semaine

%B

Nom du mois

%d

Jour du mois (de 01 à 31)

%H

Heure (de 00 à 23)

%M

Minute (entre 00 et 59)

%S

Seconde (de 00 à 59)

%Y

Année

Donc pour afficher la date telle qu'on y est habitué en France :

time.strftime("%A %d %B %Y %H:%M:%S")

Mais… c'est en anglais !

Eh oui. Mais avec ce que vous savez déjà et ce que vous allez voir par la suite, vous n'aurez pas de difficulté à personnaliser tout cela !

Bien d'autres fonctions

Le module time propose bien d'autres fonctions. Je ne vous ai montré que celles que j'utilise le plus souvent tout en vous présentant quelques concepts du temps utilisé en informatique. Si vous voulez aller plus loin, vous savez quoi faire… non ? Allez, je vous y encourage fortement donc je vous remets le lien vers la documentation du module time.

Le module datetime

Le module datetime propose plusieurs classes pour représenter des dates et heures. Vous n'allez rien découvrir d'absolument spectaculaire dans cette section mais nous nous avançons petit à petit vers une façon de gérer les dates et heures qui est davantage orientée objet.

Encore et toujours, je ne prétends pas remplacer la documentation. Je me contente d'extraire de celle-ci les informations qui me semblent les plus importantes. Je vous encourage, là encore, à jeter un coup d'œil du côté de la documentation du module datetime.

Représenter une date

Vous le reconnaîtrez probablement avec moi, c'est bien d'avoir accès au temps actuel avec une précision d'une seconde sinon plus… mais parfois, cette précision est inutile. Dans certains cas, on a juste besoin d'une date, c'est-à-dire un jour, un mois et une année.
Il est naturellement possible d'extraire cette information de notre timestamp. Le module datetime propose une classe date, représentant une date, rien qu'une date.

L'objet possède trois attributs :

  • year : l'année ;

  • month : le mois ;

  • day : le jour du mois.

Comment fait-on pour construire notre objet date ?

Il y a plusieurs façons de procéder. Le constructeur de cette classe prend trois arguments qui sont, dans l'ordre, l'année, le mois et le jour du mois.

>>> import datetime
>>> date = datetime.date(2010, 12, 25)
>>> print(date)
2010-12-25
>>>

Il existe deux méthodes de classe qui peuvent vous intéresser :

  • date.today() : renvoie la date d'aujourd'hui ;

  • date.fromtimestamp(timestamp) : renvoie la date correspondant au timestamp passé en argument.

Voyons en pratique :

>>> import time
>>> import datetime
>>> aujourdhui = datetime.date.today()
>>> aujourdhui
datetime.date(2011, 2, 14)
>>> datetime.date.fromtimestamp(time.time()) # Équivalent à date.today
datetime.date(2011, 2, 14)
>>>

Et bien entendu, vous pouvez manipuler ces dates simplement et les comparer grâce aux opérateurs usuels, je vous laisse essayer !

Représenter une heure

C'est moins courant mais on peut également être amené à manipuler une heure, indépendemment de toute date. La classe time du module datetime est là pour cela.

On construit une heure avec non pas trois mais cinq paramètres, tous optionnels :

  • hour (0 par défaut) : les heures, valeur comprise entre 0 et 23 ;

  • minute (0 par défaut) : les minutes, valeur comprise entre 0 et 59 ;

  • second (0 par défaut) : les secondes, valeur comprise entre 0 et 59 ;

  • microsecond (0 par défaut) : la précision de l'heure en micro-secondes, entre 0 et 1.000.000 ;

  • tzinfo (None par défaut) : l'information de fuseau horaire (je ne détaillerai pas cette information ici).

Cette classe est moins utilisée que datetime.date mais elle peut se révéler utile dans certains cas. Je vous laisse faire quelques tests, n'oubliez pas de vous reporter à la documentation du module datetime pour plus d'informations.

Représenter des dates et heures

Et nous y voilà ! Vous n'allez pas être bien surpris par ce que nous allons aborder. Nous avons vu une manière de représenter une date, une manière de représenter une heure, mais on peut naturellement représenter une date et une heure dans le même objet, ce sera probablement la classe que vous utiliserez le plus souvent. Celle qui nous intéresse s'appelle datetime, comme son module.

Elle prend d'abord les paramètres de datetime.date (année, mois, jour) et ensuite les paramètres de datetime.time (heures, minutes, secondes, micro-secondes et fuseau horaire).

Voyons dès à présent les deux méthodes de classe que vous utiliserez le plus souvent :

  • datetime.now() : renvoie l'objet datetime avec la date et l'heure actuelles ;

  • datetime.fromtimestamp(timestamp) : renvoie la date et l'heure d'un timestamp précis.

>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2011, 2, 14, 5, 8, 22, 359000)
>>>

Il y a bien d'autres choses à voir dans ce module datetime. Si vous êtes curieux ou que vous avez des besoins plus spécifiques, que je n'aborde pas ici, référez-vous à la documentation officielle du module.

En résumé

  • Le module time permet, entre autres, d'obtenir la date et l'heure de votre système.

  • La fonction time du module time renvoie le timestamp actuel.

  • La méthode localtime du module time renvoie un objet isolant les informations d'un timestamp (la date et l'heure).

  • Le module datetime permet de représenter des dates et heures.

  • Les classes date, time et datetime permettent respectivement de représenter des dates, des heures, ainsi que des ensembles « date et heure ».

Example of certificate of achievement
Example of certificate of achievement