Fuseaux horaires en C++ : comment arrêter de se perdre dans les fuseaux horaires

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Pourquoi le temps est un casse-tête (et comment C++ peut aider)

\n

Imaginez : votre serveur traite des commandes de New York, Londres et Tokyo. Vous enregistrez l'heure de création de la commande en UTC, puis vous affichez à l'utilisateur : « Votre commande a été créée à 03:15 ». Pour un habitant de New York, il est 22:15 la veille, pour un Londonien, 04:15 du matin, et un Tokyoïte se réveillera carrément d'une notification en pleine nuit. Un problème classique qui transforme un simple journal en casse-tête.

\n

En C++, il n'y a pas eu pendant longtemps de bibliothèque standard correcte pour travailler avec les fuseaux horaires. Les développeurs devaient soit se débattre avec time_t et struct tm, soit utiliser des bibliothèques lourdes comme Boost.DateTime. Mais avec l'arrivée de C++20, la situation a radicalement changé. La bibliothèque std::chrono s'est dotée d'un support complet des fuseaux horaires. Et bien que de nombreux compilateurs rattrapent encore la norme, nous allons voir comment écrire dès aujourd'hui un code propre et portable pour travailler avec les fuseaux horaires en C++.

\n

Dans cet article, je vais vous montrer comment transformer le chaos des fuseaux horaires en un système structuré en C++. Vous apprendrez à travailler avec std::chrono::tzdb, à convertir l'UTC en heure locale, à prendre en compte l'heure d'été et à éviter les erreurs typiques.

\n\n

Les bases : qu'est-ce qu'un fuseau horaire en C++ du point de vue de chrono

\n

En C++20, un fuseau horaire n'est pas simplement un décalage en heures par rapport à UTC. C'est un objet complet qui connaît l'historique des changements d'heure dans la région : quand les horloges ont été avancées ou reculées, quand le passage à l'heure d'été a été annulé et quelles règles y sont en vigueur. Toutes ces informations sont stockées dans la base de données des fuseaux horaires (tzdb), qui est intégrée à la bibliothèque standard.

\n\n

Types clés pour travailler avec les fuseaux horaires

\n

Pour ne pas vous perdre, retenez trois types principaux :

\n
    \n
  • std::chrono::time_zone — représente un fuseau horaire spécifique (par exemple, "America/New_York").
  • \n
  • std::chrono::zoned_time — une combinaison « fuseau horaire + instant dans le temps ». C'est le type le plus pratique pour stocker et afficher l'heure en tenant compte du fuseau.
  • \n
  • std::chrono::time_zone_link — des noms alternatifs pour les zones (par exemple, "US/Eastern" peut être un lien vers "America/New_York").
  • \n
\n\n

Obtenir la liste de tous les fuseaux horaires

\n

Commençons par quelque chose de simple : affichons tous les fuseaux horaires disponibles. C'est utile lorsque vous permettez à l'utilisateur de choisir son fuseau horaire.

\n\n
#include <iostream>\n#include <chrono>\n#include <string>\n\nint main() {\n    // Accéder à la base de données des fuseaux horaires\n    const auto& tzdb = std::chrono::get_tzdb();\n    \n    // Afficher les noms de toutes les zones\n    std::cout << "Fuseaux horaires disponibles (" << tzdb.zones.size() << ") :\\n";\n    for (const auto& zone : tzdb.zones) {\n        std::cout << zone.name() << '\\n';\n    }\n    return 0;\n}
\n\n

Notez que get_tzdb() renvoie une référence constante. La base de données est chargée une seule fois lors du premier appel et est mise en cache. Cela signifie que vous pouvez appeler cette fonction en toute sécurité dans différentes parties du programme — le surcoût n'aura lieu que lors du premier accès.

\n\n

Conversion de l'heure entre fuseaux horaires en C++

\n

Passons maintenant à l'essentiel : la conversion. Supposons que vous ayez une heure en UTC et que vous souhaitiez l'afficher à l'utilisateur dans son fuseau local. Ou l'inverse : l'utilisateur saisit une date dans son heure locale et vous devez l'enregistrer en UTC.

\n\n

De l'UTC à l'heure locale

\n

Scénario : le serveur a reçu l'heure d'un événement en UTC (par exemple, 2024-12-01 15:30:00 UTC). Il faut l'afficher pour la zone "Europe/Moscow".

\n\n
#include <iostream>\n#include <chrono>\n#include <format> // C++20 pour le formatage\n\nint main() {\n    using namespace std::chrono;\n    \n    // 1. Créer un instant dans le temps en UTC\n    // 2024-12-01 15:30:00 UTC\n    auto tp = sys_days{December / 1 / 2024} + 15h + 30min;\n                

Blogs

Book Recommendations