Introduction : Pourquoi les dates vous donnent-elles mal à la tête ?
Si vous avez déjà écrit du code en C# et avez dû transmettre une date et une heure entre un serveur à Moscou et un client à New York, vous avez sûrement remarqué des bugs étranges : « Pourquoi j’ai la date de demain ? », « D’où viennent ces 3 heures ? ». Une situation familière ?
Dans .NET, il existe deux outils principaux pour travailler avec les dates : DateTime et DateTimeOffset. À première vue, ils se ressemblent — tous deux stockent une date et une heure. Mais la différence entre eux est cruciale, et un mauvais choix peut entraîner des erreurs catastrophiques dans la logique métier.
Dans ce tutoriel, nous allons analyser DateTime vs DateTimeOffset avec des exemples concrets, comprendre quand utiliser l’un ou l’autre, et oublier à jamais la confusion liée aux fuseaux horaires. C’est parti !
Qu’est-ce que DateTime ? (Et pourquoi c’est un piège)
DateTime est une structure qui stocke la date et l’heure. Elle existe dans .NET depuis la toute première version. Mais elle a une particularité : elle ne stocke pas d’information sur le fuseau horaire. Enfin, elle en stocke, mais uniquement sous forme d’un indicateur Kind :
DateTimeKind.Unspecified— fuseau non spécifié (par défaut).DateTimeKind.Utc— temps UTC.DateTimeKind.Local— heure locale du système.
Le problème est que cet indicateur n’est qu’une information. Il ne convertit pas automatiquement l’heure. Imaginez que vous enregistrez dans une base de données un DateTime avec Kind = Local sur un serveur à Moscou. Ensuite, vous lisez cette date sur un serveur à Vladivostok. Que se passe-t-il ? Exactement — le programme voit que Kind = Local et pense qu’il s’agit de l’heure locale de Vladivostok. Mais en réalité, c’est l’heure de Moscou. Une catastrophe absolue.
// Exemple du problème avec DateTimeDateTime moscowTime = new DateTime(2025, 3, 15, 14, 0, 0, DateTimeKind.Local);Console.WriteLine(moscowTime); // 15.03.2025 14:00:00 (supposé être MSK)
// Si ce code est exécuté sur un serveur avec le fuseau horaire UTC+10 (Vladivostok)// DateTime sera interprété comme l’heure locale de Vladivostok !// Ce qui entraînera une erreur de 7 heures.Qu’est-ce que DateTimeOffset ? (Le sauveur des développeurs)
DateTimeOffset est une structure plus intelligente, apparue dans .NET Framework 3.5. Elle stocke la date, l’heure et le décalage par rapport à UTC (Offset). Le décalage est le nombre d’heures et de minutes de différence entre votre heure locale et UTC.
Par exemple : 2025-03-15 14:00:00 +03:00 — c’est l’heure à Moscou (UTC+3). Si vous transmettez cette valeur à un serveur à Vladivostok (UTC+10), .NET comprendra : « Ah, c’est +03, donc UTC = 11:00. Maintenant, je peux facilement recalculer en heure locale : 21:00 ». Pas de magie — que des mathématiques pures.
// Exemple avec DateTimeOffsetDateTimeOffset moscowOffset = new DateTimeOffset(2025, 3, 15, 14, 0, 0, TimeSpan.FromHours(3));Console.WriteLine(moscowOffset); // 15.03.2025 14:00:00 +03:00
// Maintenant, même sur un serveur à Vladivostok, nous connaissons le décalage exact// et pouvons afficher correctement l’heure pour l’utilisateurDifférences clés : DateTime vs DateTimeOffset
Résumons tout cela dans un tableau clair. Cela vous aidera à choisir rapidement dans une situation donnée.
1. Stockage de l’information sur le fuseau horaire
- DateTime : Stocke uniquement l’indicateur Kind (Unspecified, Utc, Local). Ne stocke pas le décalage lui-même.
- DateTimeOffset : Stocke le décalage exact par rapport à UTC (par exemple, +03:00, -05:00).
2. Comparaison des valeurs
- DateTime : Compare la valeur « brute ». Si vous avez 10:00 UTC et 10:00 MSK (UTC+3), alors
DateTime.Equals()dira qu’elles sont égales. Alors qu’en réalité, ce sont des instants différents. - DateTimeOffset : Compare selon l’instant temporel (UTC). 10:00 UTC et 13:00 MSK seront