CodeGym /Cours /C# SELF /Travailler avec les fuseaux horaires :

Travailler avec les fuseaux horaires : TimeZoneInfo

C# SELF
Niveau 15, Leçon 2
Disponible

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
Id
Identifiant système du timezone (utilisé pour la recherche)
DisplayName
Description pour l'utilisateur (avec heures et villes)
StandardName
Nom du temps "standard"
DaylightName
Nom du temps pour l'heure d'été
BaseUtcOffset
Décalage par rapport à UTC (ex : +01:00 pour Berlin)
SupportsDaylightSavingTime
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é.
2
Mission
C# SELF, niveau 15, leçon 2
Bloqué
Affichage du fuseau horaire local et UTC
Affichage du fuseau horaire local et UTC
2
Mission
C# SELF, niveau 15, leçon 2
Bloqué
Conversion de l'heure entre deux fuseaux horaires
Conversion de l'heure entre deux fuseaux horaires
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION