1. Découverte du type DateTime
La date et l'heure, c'est vraiment la base de toute logique métier, tu peux pas l'ignorer même dans les projets les plus simples. Souvent, tu dois savoir quand un utilisateur s'est inscrit, quand envoyer un mail, gérer correctement les horaires de vols, les fuseaux horaires — partout des dates ! Mais, en vrai, bosser avec les dates et l'heure, c'est un des trucs les plus piégeux en prog. 😅
C# propose deux types super importants pour gérer le temps : DateTime et DateTimeOffset. Pour faire simple — l'un pour les scénarios basiques, l'autre pour tout ce qui touche aux fuseaux horaires et au stockage précis du temps.
C'est quoi DateTime ?
Le type DateTime, c'est une structure définie dans l'espace de noms System. Elle sert à stocker une date et une heure avec une précision de 100 nanosecondes (1/10-milliardième de seconde).
- Type valeur (struct), donc copié par valeur.
- Contient à la fois la date et l'heure.
- Permet de stocker juste une date (2025-05-24) ou une date avec l'heure (2025-05-24 15:17:42).
- Il "ne connaît pas" les fuseaux horaires, sauf si tu le précises.
2. Créer un DateTime
Y'a plusieurs façons, on va voir les principales.
1. Date et heure actuelles
DateTime now = DateTime.Now; // Heure locale de l'ordi
DateTime utcNow = DateTime.UtcNow; // Heure UTC (Greenwich)
- Now — c'est "comme sur ton ordi", en tenant compte du fuseau horaire local de Windows.
- UtcNow — "universel", donc temps coordonné mondial. Super pratique pour stocker l'heure, par exemple dans les bases de données ou les systèmes qui tournent partout dans le monde.
2. Constructeurs
// Année, mois, jour
var date1 = new DateTime(2025, 5, 24);
// Année, mois, jour, heures, minutes, secondes
var date2 = new DateTime(2025, 5, 24, 12, 0, 0);
// Année, mois, jour, heures, minutes, secondes, millisecondes
var date3 = new DateTime(2025, 5, 24, 12, 0, 0, 500);
Les mois ne commencent pas à zéro ! Donc janvier c'est 1, décembre — 12.
3. Parser depuis une chaîne
Très souvent, la date arrive sous forme de chaîne ! Par exemple, l'utilisateur tape la date à la main.
string userInput = "2025-05-24 18:30";
DateTime parsed = DateTime.Parse(userInput); // Peut lancer une exception !
Pour parser en mode safe — utilise TryParse :
string input = "2025-05-24 18:30";
if (DateTime.TryParse(input, out DateTime result))
{
Console.WriteLine($"Conversion réussie : {result}");
}
else
{
Console.WriteLine("Impossible de convertir la chaîne en date.");
}
4. Obtenir la date "sans l'heure"
DateTime today = DateTime.Today; // Aujourd'hui, mais heure = 00:00:00
Extraire les composants de la date et de l'heure
Tu peux choper toutes les propriétés direct :
var dt = new DateTime(2025, 5, 24, 15, 17, 42);
int year = dt.Year; // 2025
int month = dt.Month; // 5 (mai)
int day = dt.Day; // 24
int hour = dt.Hour; // 15
int minute = dt.Minute; // 17
int second = dt.Second; // 42
DayOfWeek dow = dt.DayOfWeek; // Vendredi
3. Bosser avec le type DateTime
Addition et soustraction de dates
Le temps en prog, ça file vite, et pour pas te prendre la tête à calculer "combien d'heures avant la deadline", utilise les méthodes de la classe :
DateTime now = DateTime.Now;
DateTime tomorrow = now.AddDays(1); // Demain
DateTime afterFiveHours = now.AddHours(5); // Dans 5 heures
DateTime inTenMinutes = now.AddMinutes(10); // Dans 10 minutes
Différence entre deux dates : TimeSpan
La différence entre deux dates, c'est une valeur à part, le type TimeSpan :
DateTime deadline = new DateTime(2026, 6, 1);
DateTime now = DateTime.Now;
TimeSpan untilDeadline = deadline - now;
Console.WriteLine($"Jours restants avant la deadline : {untilDeadline.Days}");
Console.WriteLine($"Heures restantes avant la deadline : {untilDeadline.TotalHours:N2}");
TimeSpan — c'est une "différence", pas une "date/heure précise" !
Vérifier si une date est dans le futur/le passé
if (deadline > now)
Console.WriteLine("La deadline est encore devant !");
else
Console.WriteLine("La deadline est déjà passée ! Dépêche-toi de rendre le taf !");
4. Comment les dates sont stockées sous le capot
Pour faciliter l'addition et la soustraction de dates, les devs ont décidé de stocker toutes les dates comme le nombre de secondes écoulées depuis le début de notre ère. Les valeurs de la plage :
| Propriété | Valeur |
|---|---|
| Date minimale | = 0001-01-01 00:00:00 |
| Date maximale | = 9999-12-31 23:59:59.9999999 |
| Unité de mesure | 1 tick = 100 nanosecondes |
DateTime ne stocke pas juste le nombre de secondes, mais le nombre de "ticks" (ticks) depuis une date spéciale — le 1er janvier de l'an 0001 (ouais, les devs connaissent pas les dinos, leur calendrier est plus strict). Un tick = 100 nanosecondes.
5. Le type DateTimeOffset
Parfois, DateTime ne suffit pas. Prends un cas classique : une boîte bosse dans deux pays, avec des fuseaux horaires différents, et toutes les réunions sont planifiées "à mon heure". Tu fais comment ?
L'heure stockée comme DateTime est souvent "abstraite" : c'est juste des chiffres et des ticks, tant que tu précises pas dans quel fuseau c'était. Par exemple, si tu reçois "2025-05-24 15:00", tu peux pas savoir — c'est l'heure de Nairobi ? Bagdad ? Berlin ? (et si y'a l'heure d'été — accroche-toi !).
Du coup, pour tout ce qui touche à un instant précis dans le temps, pas juste une "date de calendrier", y'a un deuxième type — DateTimeOffset. Créer un DateTimeOffset avec un décalage (genre Nairobi +3 par rapport à UTC) :
var localTime = new DateTimeOffset(2025, 5, 24, 15, 0, 0, TimeSpan.FromHours(3));
Utilise DateTimeOffset si :
- Tu dois connaître l'instant précis (genre pour les logs côté serveur).
- Ton appli gère des utilisateurs dans plusieurs fuseaux horaires.
- Tu dois stocker/envoyer l'heure avec le fuseau (genre pour les transactions, événements, plannings).
6. Comment créer un DateTimeOffset ?
- Moment actuel
DateTimeOffset now = DateTimeOffset.Now; // Heure locale + décalage DateTimeOffset utc = DateTimeOffset.UtcNow; // UTC (décalage 0) - Création explicite
// Année, mois, jour, heure, minute, seconde, décalage (genre +2 heures) DateTimeOffset custom = new DateTimeOffset(2025, 5, 24, 20, 0, 0, TimeSpan.FromHours(2)); - Conversion depuis DateTime
DateTime dt = DateTime.Now; DateTimeOffset dto = new DateTimeOffset(dt); // Le décalage local sera pris automatiquement
Extraire les composants
DateTimeOffset dto = DateTimeOffset.Now;
var datePart = dto.Date; // Juste la date
var timePart = dto.TimeOfDay; // Juste l'heure
var offset = dto.Offset; // Décalage par rapport à UTC, genre 03:00:00
Conversion entre fuseaux horaires
La magie des décalages :
// On récupère la date en UTC
var now = DateTimeOffset.Now;
var utc = now.ToUniversalTime();
Console.WriteLine(utc); // Heure de Greenwich
// On convertit dans un autre fuseau
var berlinTime = utc.ToOffset(TimeSpan.FromHours(2));
Console.WriteLine(berlinTime); // Pour Berlin (CET +2)
7. Quand utiliser DateTime et quand — DateTimeOffset ?
La philosophie du choix
Quand c'est un truc simple et local — genre un anniversaire, la date de publication d'un article ou une deadline pour un sondage à 15h, en général DateTime suffit. Dans ces cas-là, l'heure absolue n'est pas critique, ce qui compte c'est juste que l'événement ait eu lieu à un certain jour et heure, sans se soucier du fuseau.
Mais si tu dois fixer un instant précis avec le fuseau, genre dans les logs, les transactions ou les systèmes distribués — mieux vaut utiliser DateTimeOffset. Comme ça, tu te perds pas quand tu échanges l'heure entre systèmes, surtout s'ils sont dans des fuseaux différents.
| Scénario | Type | Pourquoi |
|---|---|---|
| Anniversaire | |
Seule la date compte, le fuseau on s'en fiche (en général) |
| Heure de connexion | |
Faut connaître l'instant précis et le décalage |
| Date d'expiration d'un produit | |
Date de fin, le fuseau n'a pas d'importance |
| Heure d'un événement dans un log | |
Il vaut mieux toujours stocker avec le décalage |
GO TO FULL VERSION