Parcours
/
Julia
Julia
/
Exercices
/
Réservations beauté
Réservations beauté

Réservations beauté

Exercice d'apprentissage

Introduction

« Les dates et les heures, on apprend ça à de jeunes enfants. Qu'est-ce que ça peut bien avoir de compliqué ? »

Beaucoup de programmeurs ont fait cette erreur, et l'expérience qui s'ensuit a tendance à nuire à leur santé et à leur bonheur.

Toute personne qui fait de la programmation non triviale avec des dates et des heures devrait au moins être prête à comprendre et à atténuer les problèmes potentiels.

Ce document tente de donner un aperçu de la façon dont Julia gère les dates et les heures, mais il faudra consulter le manuel pour plus de détails. Il existe aussi un Wikibook dont certains lecteurs trouveront les explications plus claires, et qui contient un diagramme utile de la hiérarchie des types.

Le module Dates

L'essentiel des fonctionnalités de base se trouve dans Dates, un module inclus dans une installation par défaut, mais qui ne fait pas partie de la bibliothèque standard.

Pour utiliser ce module, deux options s'offrent à toi :

  1. Ajouter import Dates, puis faire précéder tous les appels de fonction de Dates.
  2. Ajouter using Dates, ce qui importe tout le module dans l'espace de noms courant (à l'exception de quelques noms problématiques).
# option 1
julia> import Dates

julia> Dates.now()
2025-06-21T16:02:39.080

julia> now()  # wrong: need to include `Dates.` after an import
ERROR: UndefVarError: `now` not defined in `Main`


# option 2
julia> using Dates

julia> now()  # functions are now in the namespace
2025-06-21T16:03:04.161

Le module Dates est vaste et complexe, mais il fournit quatre grands types de fonctionnalités :

  • Dates.Date, qui comprend le jour, le mois et l'année, mais pas l'heure.
  • Dates.Time, qui comprend l'heure, mais pas la date.
  • Dates.DateTime, qui combine date et heure.
  • Dates.Period, qui gère les intervalles de temps et de date.

Note qu'un DateTime ne contient généralement pas d'information de fuseau horaire (Python qualifierait cela de datetime « naïve »). Une exception est now(), qui récupère l'heure locale de l'horloge du système et peut la convertir en UTC si nécessaire.

Les besoins les plus fréquents sont sans doute les suivants :

  • Analyser un format d'entrée approprié pour construire un type Dates.
  • Obtenir le format numérique ou textuel souhaité à partir d'un type Dates.
  • Appliquer un décalage à une valeur Date, Time ou DateTime.
  • Calculer l'intervalle entre deux de ces valeurs.
  • Obtenir la date courante (avec today()) et/ou l'heure courante (avec now()).
Note

Pour limiter les distractions visuelles, la plupart des exemples de code du reste de ce document supposent using Dates, et évitent d'inclure le nom du module Dates. dans les appels de fonction.

Formats de date et d'heure

Il existe de nombreuses façons d'écrire les dates et les heures, qui ont tendance à dépendre de la culture. Les dates entièrement numériques comme « 7/6/23 » sont ambiguës, sources de confusion, et ont provoqué de nombreuses erreurs coûteuses dans des organisations multinationales (l'auteur parle là d'une amère expérience personnelle).

La norme internationale est définie dans ISO 8601, avec deux avantages principaux :

  • L'analyse est rapide et sans ambiguïté.
  • Le tri est facile, car la date et l'heure peuvent être traitées comme du texte normal et triées par ordre alphabétique.

On a vu dans un exemple précédent que Date.now() renvoyait 2025-06-21T16:03:04.161.

Cette représentation se compose de plusieurs éléments :

  • YYYY-MM-DD pour la partie date.
  • hh:mm:ss pour la partie heure.
  • Facultativement, des millisecondes (ou une unité encore plus petite) après la virgule.

D'autres formats de chaînes de caractères seront abordés dans une section ultérieure.

Dates

Dates.Date est un type relativement simple, qui ne représente qu'une date et ne comprend ni les heures ni les fuseaux horaires.

# constructor with year, month, day arguments
julia> date1 = Date(2025, 06, 23)
2025-06-23

# constructor with ISO 8601 string
julia> date2 = Date("2025-06-23")
2025-06-23

julia> date1 == date2
true

julia> typeof(date1)
Date

Il existe des fonctions d'accès pour les différentes parties de la date, et celles-ci vont par paires, distinguées par la casse.

# lowercase returns an integer
julia> month(date1)
6

julia> typeof(month(date1))
Int64

# Propercase returns a Period type
julia> Month(date1)
6 months

julia> typeof(Month(date1))
Month

Fonctions d'interrogation

Il existe tout un éventail de fonctions qui ont une certaine compréhension du calendrier. L'exemple suivant n'en montre que quelques-unes.

julia> date1
2025-06-23

julia> dayofweek(date1) # 1 = Monday, 7 = Sunday
1

julia> dayname(date1)
"Monday"

julia> daysinmonth(date1)
30

julia> isleapyear(date1)
false

julia> lastdayofmonth(date1)
2025-06-30

Heures

Dates.Time est le type de base qui ne représente qu'une heure. Il ne comprend pas les dates : les heures reviennent automatiquement à Time(0, 0, 0) à minuit.

Le format complet du constructeur est Time(hour, min, sec, millisec, microsec), ou son équivalent ISO 8601.

Tous les paramètres sont facultatifs et prennent la valeur 0 par défaut.

julia> Time(14, 57, 25, 142)
14:57:25.142

julia> Time("14:57:25.142")
14:57:25.142

julia> Time(14, 57, 25, 142, 32)
14:57:25.142032

Comme pour Date, les différentes parties sont accessibles via des fonctions d'accès :

julia> minute(t) # => integer
57

julia> Minute(t) # => Period
57 minutes

DateTimes

Dates.DateTime combine la plupart des caractéristiques des types Date et Time.

julia> dt1 = DateTime(2025, 6, 23, 14, 57, 25, 142)
2025-06-23T14:57:25.142

# date1 and t were defined in previous examples
julia> dt2 = DateTime(date1, t)
2025-06-23T14:57:25.142

Les paramètres année, mois et jour prennent la valeur 1 par défaut, et les paramètres d'heure prennent tous 0 par défaut.

Ce n'est pas toujours facile de garder tous ces paramètres dans le bon ordre, donc le format ISO peut être préférable pour les entrées.

Sinon, on peut construire un DateTime à partir d'une Date et d'une Time, comme dans l'exemple ci-dessus.

Périodes

Chacune des composantes de date et d'heure a son propre type Period, de Year jusqu'à Nanosecond, qui représente un intervalle de temps. Ils sont particulièrement utiles pour les opérations arithmétiques.

julia> dt1
2025-06-23T14:57:25.142

julia> Year(21)
21 years

julia> Second(61)
61 seconds

julia> dt1 + Year(21) - Second(61)
2046-06-23T14:56:24.142

julia> Date(2025, 07, 03) - Date(2025, 04, 25)
69 days

Lorsqu'on travaille avec les types Period, Julia essaie de gérer intelligemment les irrégularités du calendrier, comme la longueur des mois, en arrondissant si nécessaire.

# February has fewer days than January
julia> Date(2025, 1, 31) + Month(1) 
2025-02-28

Représentations sous forme de chaînes de caractères

On a mentionné plus haut la norme ISO 8601, qui est la représentation par défaut des dates et des heures de Julia lors du formatage ou de l'analyse de strings.

Évidemment, beaucoup d'autres formats sont fréquemment utilisés, souvent selon des usages culturels propres. Pour les gérer, Julia dispose du type DateFormat, que l'on peut construire à partir d'une chaîne de format de complexité arbitraire.

# dateformat"" string syntax
julia> dtfmt = dateformat"d/m/y"
dateformat"d/m/y"

julia> typeof(dtfmt)
DateFormat{Symbol("d/m/y"), Tuple{Dates.DatePart{'d'}, Dates.Delim{Char, 1}, Dates.DatePart{'m'}, Dates.Delim{Char, 1}, Dates.DatePart{'y'}}}

# DateFormat constructor
julia> DateFormat("d/m/y")
dateformat"d/m/y"

L'exemple ci-dessus est très simple : juste une date au format jour/mois/année courant en Europe. Deux variantes de la syntaxe sont présentées, mais le résultat est identique.

Un DateFormat peut ensuite servir à analyser n'importe quelle string appropriée :

julia> DateTime("14/7/2023", dtfmt)
2023-07-14T00:00:00

Créer un DateFormat implique un surcoût important, donc effectuer cette étape une seule fois (comme ici avec dtfmt) améliore les performances lorsqu'on parcourt de nombreuses strings de date et d'heure.

Les formats peuvent être bien plus complexes que cela, alors consulte le manuel pour les détails.

Le même DateFormat peut aussi servir à afficher une date et une heure dans le format de chaîne souhaité, à l'aide de la fonction Dates.format().

Malheureusement, il semble y avoir un conflit d'espace de noms avec format (du moins avec Julia 1.11.5), donc mieux vaut inclure le préfixe Dates. même après using Dates.

julia> dt1
2025-06-23T14:57:25.142

julia> Dates.format(dt1, dateformat"e, u d")
"Mon, Jun 23"

Comme documenté, "e, u d" donne la représentation textuelle abrégée du jour de la semaine et du mois.

La représentation textuelle utilise l'anglais par défaut. D'autres langues peuvent être ajoutées, mais la prise en charge est actuellement loin d'être optimale.

Instructions

Dans cet exercice, tu vas travailler sur un planificateur de rendez-vous pour un salon de beauté à New York, ouvert le 15 septembre 2012.

Tu as cinq tâches, qui portent toutes sur des dates de rendez-vous. Les horaires sont au format 24 heures (sans AM/PM).

1. Analyse une date de rendez-vous entièrement numérique

Implémente la fonction schedule_appointment() pour analyser une représentation textuelle d'une date de rendez-vous et la convertir au format DateTime correspondant.

Note que l'entrée suit l'ordre américain mois/jour/année.

julia> schedule_appointment("07/25/2023 13:45:00")
2023-07-25T13:45:00

2. Vérifie si un rendez-vous est déjà passé

Implémente la fonction has_passed() qui prend une date de rendez-vous et vérifie si le rendez-vous se situe dans le passé :

julia> has_passed(DateTime(1999, 12, 31, 9, 0, 0))
true

3. Vérifie si un rendez-vous a lieu l'après-midi

Implémente la fonction is_afternoon_appointment() qui prend une date de rendez-vous et vérifie si le rendez-vous a lieu l'après-midi (>= 12:00 et < 18:00) :

julia> is_afternoon_appointment(DateTime(2023, 3, 29, 15, 0, 0))
true

4. Décris la date et l'heure du rendez-vous

Implémente la fonction description() qui prend une date de rendez-vous et renvoie une description de cette date et de cette heure :

julia> describe(DateTime(2023, 3, 29, 15, 0, 0))
"You have an appointment on Wednesday, March 29, 2023 at 15:00"

5. Renvoie la date d'anniversaire

Implémente la fonction anniversary_date() qui renvoie la date d'anniversaire de cette année, à savoir le 15 septembre :

julia> anniversary_date()  # run during 2025
2025-09-15
Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet
Julia Exercism

Prêt à commencer Réservations beauté ?

Inscris-toi sur Exercism pour apprendre et maîtriser Julia avec 35 concepts128 exercices, et un vrai mentorat humain, le tout gratuitement.