1. Introduction
Si tu penses que les timezones c'est juste "ajouter/enlever quelques heures", tu vas vite ressentir toute la douleur de la plupart des devs sur cette planète. Les fuseaux horaires, les changements d'heure d'été/hiver, les exceptions cheloues quand tu veux "convertir l'heure dans une autre région" — tout ça peut causer des bugs bien galère à trouver et encore plus à expliquer aux users.
Le pire : il n'y a jamais eu de "compréhension universelle" du temps dans le monde — par exemple, deux pays voisins peuvent gérer l'heure d'été différemment, et parfois les décisions de changement sont prises en plein milieu d'année (ouais, c'est vraiment arrivé !). Exemple : en 2011, Samoa a "sauté" un jour entier et a changé de côté par rapport à la ligne de changement de date.
Mais C# et .NET te filent des outils puissants pour au moins essayer de gérer ça. Aujourd'hui, on va faire connaissance avec notre sauveur — le type TimeZoneInfo et ses fonctions qui vont t'aider, toi et ton appli.
Pourquoi et quand tu as besoin de gérer les timezones
- Quand les users/serveurs sont dans différents coins du monde
- Quand tu stockes la date et l'heure en base en UTC, mais tu veux l'afficher à l'utilisateur dans son heure locale
- Pour calculer des plannings, rappels, événements en ligne ("Le webinaire commence à 19:00 à Berlin — et chez toi ?")
- Quand tu bosses sur des systèmes corporate/globaux (genre compta ou CRM pour un business international)
Vue d'ensemble du type TimeZoneInfo
TimeZoneInfo — c'est une classe spéciale dans .NET, faite pour représenter les infos sur un fuseau horaire : son décalage par rapport à UTC, son nom, s'il gère l'heure d'été, etc.
Contrairement à l'ancienne classe TimeZone, qui connaît juste le fuseau "local" et "UTC", TimeZoneInfo te donne accès à tous les fuseaux enregistrés sur le système (et même à ceux que tu crées à la main).
2. Récupérer des infos sur les timezones
Fuseau local et UTC
Récupérer les infos sur le fuseau local, c'est super simple :
// Local (c'est-à-dire là où tourne ton programme)
TimeZoneInfo local = TimeZoneInfo.Local;
// Toujours UTC
TimeZoneInfo utc = TimeZoneInfo.Utc;
Console.WriteLine(local.DisplayName); // Par exemple : (UTC+01:00) Berlin, Vienna
Console.WriteLine(utc.DisplayName); // (UTC) Coordinated Universal Time
Toutes les timezones dispo
Souvent, tu dois afficher à l'utilisateur la liste de toutes les timezones possibles (genre à l'inscription sur un service) :
foreach (var tz in TimeZoneInfo.GetSystemTimeZones())
{
Console.WriteLine($"{tz.Id} | {tz.DisplayName}");
}
Ça va afficher une liste du genre :
- Central European Standard Time | (UTC+01:00) Berlin, Vienna
- Pacific Standard Time | (UTC-08:00) Pacific Time (US & Canada)
- etc.
Visualisation : propriétés principales de TimeZoneInfo
| Propriété | Description |
|---|---|
|
Identifiant système du timezone (utilisé pour la recherche) |
|
Description pour l'utilisateur (avec heures et villes) |
|
Nom du temps "standard" |
|
Nom du temps pour l'heure d'été |
|
Décalage par rapport à UTC (ex : +01:00 pour Berlin) |
|
True si le timezone gère l'heure d'été/hiver |
3. Conversion d'heure entre timezones
Voilà pourquoi tout ça existe ! Tu dois :
- Convertir l'heure d'une zone à une autre (genre le serveur enregistre en UTC, mais tu affiches à l'utilisateur dans son fuseau)
- Gérer correctement le passage à l'heure d'été/hiver
Synthaxe générale
DateTime utcNow = DateTime.UtcNow;
// Par exemple, on convertit cette heure en fuseau Europe centrale
TimeZoneInfo europeZone = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
DateTime europeTime = TimeZoneInfo.ConvertTimeFromUtc(utcNow, europeZone);
Console.WriteLine($"UTC now: {utcNow}"); // 2024-06-20 10:30:00
Console.WriteLine($"Europe now: {europeTime}"); // 2024-06-20 11:30:00
Important : Utilise toujours UTC pour les calculs internes et le stockage, et ne convertis dans le fuseau voulu qu'à l'affichage !
Comment trouver l'identifiant du timezone ?
Sous Windows, les identifiants (Id) des timezones sont spécifiques (genre "Central European Standard Time"), alors que sous Linux/Unix — c'est souvent des identifiants IANA/Olson ("Europe/Berlin", "America/New_York").
Tu peux choper la liste des identifiants sur ta machine avec TimeZoneInfo.GetSystemTimeZones().
4. Conversion entre zones arbitraires
Imaginons que tu as une heure à Londres (GMT/UTC+0) et tu veux la convertir pour Tokyo (UTC+9) :
DateTime londonTime = new DateTime(2024, 6, 20, 12, 0, 0, DateTimeKind.Unspecified);
TimeZoneInfo londonZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
TimeZoneInfo tokyoZone = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
// Première étape : convertir l'heure en UTC (si elle est locale)
DateTime utc = TimeZoneInfo.ConvertTimeToUtc(londonTime, londonZone);
// Deuxième étape : convertir UTC en heure de Tokyo
DateTime tokyoTime = TimeZoneInfo.ConvertTimeFromUtc(utc, tokyoZone);
Console.WriteLine($"London: {londonTime} | UTC: {utc} | Tokyo: {tokyoTime}");
Gérer les passages à l'heure d'été et d'hiver
TimeZoneInfo prend en compte les changements d'heure d'été/hiver — si le fuseau le gère.
TimeZoneInfo eastern = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime dateWinter = new DateTime(2024, 1, 1, 12, 0, 0, DateTimeKind.Unspecified);
DateTime dateSummer = new DateTime(2024, 7, 1, 12, 0, 0, DateTimeKind.Unspecified);
Console.WriteLine( TimeZoneInfo.ConvertTimeToUtc(dateWinter, eastern)); // Décalage UTC-5
Console.WriteLine( TimeZoneInfo.ConvertTimeToUtc(dateSummer, eastern)); // Décalage UTC-4 — heure d'été !
Même si les USA (dans l'exemple ci-dessus) décident d'arrêter l'heure d'été (et ce genre d'initiative revient chaque année !), la base des timezones de ton OS sera mise à jour, et ton code continuera de marcher nickel.
5. Conseils pratiques et pièges fréquents
Exceptions et pièges
- Au moment du changement d'heure (genre 2h30 du mat le jour du passage à l'heure d'été/hiver), certaines heures peuvent être "inexistantes" ou "dupliquées" :
Par exemple, le jour où on recule d'une heure, 2h30 arrive deux fois — et ce n'est pas la même heure. - N'oublie pas : la liste des timezones peut changer avec les updates de l'OS ! Exemple : certains pays suppriment/ajoutent l'heure d'été.
GO TO FULL VERSION