Time Zones in C++: How to Stop Getting Confused About Time Zones

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Why Time is a Pain (and How C++ Can Help)

\n

Imagine: your server processes orders from New York, London, and Tokyo. You record the order creation time in UTC, and then show the user: "Your order was created at 03:15." For a New Yorker, that's 22:15 the previous day, for a Londoner it's 04:15 AM, and a Tokyo resident will be woken up by a notification in the middle of the night. A classic problem that turns a simple log into a puzzle.

\n

In C++, for a long time, there was no proper standard way to work with time zones. Developers either struggled with time_t and struct tm, or included heavy libraries like Boost.DateTime. But with the arrival of C++20, the situation changed dramatically. The std::chrono library gained full support for time zones. And although many compilers are still catching up to the standard, we'll look at how to write clean and portable code for working with time zones in C++ today.

\n

In this article, I'll show you how to turn the chaos of time zones into a well-organized system in C++. You'll learn to work with std::chrono::tzdb, convert UTC to local time, account for daylight saving time, and avoid common mistakes.

\n\n

Basics: What is a Time Zone in C++ from chrono's Perspective

\n

In C++20, a time zone is not just an offset in hours from UTC. It is a full-fledged object that knows the history of time changes in a region: when clocks were changed, when daylight saving time was abolished, and what rules are in effect. All this information is stored in the time zone database (tzdb), which is built into the standard library.

\n\n

Key Types for Working with Time Zones

\n

To avoid confusion, remember three main types:

\n
    \n
  • std::chrono::time_zone — represents a specific time zone (e.g., "America/New_York").
  • \n
  • std::chrono::zoned_time — a pairing of "time zone + point in time". This is the most convenient type for storing and displaying time with timezone awareness.
  • \n
  • std::chrono::time_zone_link — alternative names for zones (e.g., "US/Eastern" might be a link to "America/New_York").
  • \n
\n\n

Getting a List of All Time Zones

\n

Let's start simple: print all available time zones. This is useful when you let the user choose their time zone.

\n\n
#include <iostream>\n#include <chrono>\n#include <string>\n\nint main() {\n    // Get access to the time zone database\n    const auto& tzdb = std::chrono::get_tzdb();\n    \n    // Print the names of all zones\n    std::cout << "Available time zones (" << tzdb.zones.size() << "):\\n";\n    for (const auto& zone : tzdb.zones) {\n        std::cout << zone.name() << '\\n';\n    }\n    return 0;\n}
\n\n

Note: get_tzdb() returns a const reference. The database is loaded once on the first call and cached. This means you can safely call this function from different parts of the program — the overhead will only occur on the first call.

\n\n

Converting Time Between Time Zones in C++

\n

Now let's move to the most important part — conversion. Suppose you have a time in UTC, and you want to show it to the user in their local time zone. Or vice versa: the user enters a date in their local time, but you need to save it in UTC.

\n\n

From UTC to Local Time

\n

Scenario: the server received an event time in UTC (e.g., 2024-12-01 15:30:00 UTC). You need to display it for the "Europe/Moscow" zone.

\n\n
#include <iostream>\n#include <chrono>\n#include <format> // C++20 for formatting\n\nint main() {\n    using namespace std::chrono;\n    \n    // 1. Create a point in time in UTC\n    // 2024-12-01 15:30:00 UTC\n    auto tp = sys_days{December / 1 / 2024} + 15h + 30min;\n                

Blogs

Book Recommendations