Initialisation des systèmes...

Baptiste.Dev
Retour aux notes
LangagesIntermédiaireSérie : C# / .NET

C# : Dates et temps

DateTime, DateOnly, TimeOnly, TimeSpan, DateTimeOffset : quel type pour quel besoin, et les pièges à éviter (fuseaux, parsing, immuabilité).

Par Baptiste Vidal
2 min de lecture
Mis à jour aujourd'hui
c#csharpdatetimedateonlytimespandatetimeoffsetdatestemps

C# : Dates et temps

Le .NET propose plusieurs types pour manipuler dates et temps, et choisir le bon évite la majorité des bugs : décalages de fuseau, dates ambiguës, comparaisons fausses. Cette page est la vue d'ensemble ; chaque type a ensuite sa page détaillée.

Point commun à tous : ce sont des types valeur (struct), donc immuables. Une opération comme AddDays ne modifie rien, elle retourne une nouvelle valeur.


# La famille

TypeRôle
DateTimeune date et une heure (avec un Kind : local, UTC ou non spécifié)
DateOnlyune date seule, sans heure ni fuseau (.NET 6+)
TimeOnlyune heure d'horloge seule, sans date (.NET 6+)
TimeSpanune durée ou un écart entre deux instants
DateTimeOffsetun instant précis, avec son décalage par rapport à UTC
TimeZoneInfoles fuseaux horaires et les conversions entre eux

# Quel type pour quel besoin

Pars toujours de ce que la donnée représente vraiment :

BesoinType conseillé
Un instant unique dans le temps (log, horodatage, création d'un enregistrement)DateTimeOffset (ou DateTime en UTC)
Une date sans heure (anniversaire, date de facture, échéance)DateOnly
Une heure sans date (ouverture d'un magasin, alarme)TimeOnly
Une durée, un délai, un écartTimeSpan
Une date + heure locale simple, sans enjeu de fuseauDateTime
Convertir un instant d'un fuseau à un autreTimeZoneInfo

La règle courte : stocke en UTC, affiche en local. Ne garde une heure locale nue (DateTime.Now) que pour un affichage immédiat, jamais pour persister un instant.


# Les pièges communs

Now vs UtcNow

DateTime local = DateTime.Now;      // heure de la machine, dépend du fuseau et de l'heure d'été
DateTime utc = DateTime.UtcNow;     // heure universelle, stable partout

Persister un DateTime.Now pose problème : au changement d'heure ou sur un autre serveur, l'instant devient ambigu. Pour un horodatage, prends UtcNow ou mieux, un DateTimeOffset.

Ce sont des valeurs immuables

DateTime d = new DateTime(2026, 1, 1);
d.AddDays(10);            // INUTILE : le résultat est jeté
d = d.AddDays(10);       // BIEN : on réaffecte la nouvelle valeur

Le parsing dépend de la culture

// "01/02/2026" : 1er février ou 2 janvier ? Ça dépend de la culture !
DateTime ambigu = DateTime.Parse("01/02/2026");
 
// BIEN : format explicite et culture invariante
DateTime clair = DateTime.ParseExact("2026-02-01", "yyyy-MM-dd", CultureInfo.InvariantCulture);

Le mauvais type pour la donnée

Une date de naissance n'a ni heure ni fuseau : un DateTime t'expose à des bugs de minuit et de décalage. Utilise DateOnly. Un délai de 90 minutes n'est pas une date : c'est un TimeSpan.


# Par où continuer

Ces types sont des struct : relis la mémoire pour comprendre pourquoi une copie est indépendante de l'originale.