Working with Dates and Time in C++: From A to Z — A Complete Guide

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

Working with Dates and Time in C++: From A to Z



Working with dates and time is one of the fundamental tasks in programming. It is needed everywhere: from event logging to calculating deadlines and building charts. In C++, this area was historically not the most convenient, but with the arrival of the C++11 standard and subsequent versions (C++14, C++17, C++20), the situation has changed dramatically. In this article, we will cover all the key aspects: from classic C functions to the modern chrono library, timers, formatting, and parsing. The material will be useful for both beginners and experienced developers looking to systematize their knowledge.



1. Classic Approach: time_t and the tm Structure



Before the advent of chrono, the main tools were functions from <ctime>. This approach remains relevant for supporting legacy code and simple tasks.



Main functions:

  • time() — returns the current time as time_t (number of seconds since January 1, 1970).
  • localtime() — converts time_t to a tm structure (local time).
  • gmtime() — converts to UTC.
  • strftime() — formats tm into a string.
  • mktime() — reverse conversion: tm → time_t.


#include <iostream>#include <ctime>

int main() { // Get current time std::time_t now = std::time(nullptr);

// Convert to local time std::tm* local_tm = std::localtime(&now);

// Format into a string char buffer[80]; std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", local_tm);

std::cout << "Current time: " << buffer << std::endl; return 0;}


Disadvantages of the approach:

  • Only works with seconds (milliseconds and microseconds are unavailable).
  • Not thread-safe in multithreaded environments (use localtime_r on POSIX).
  • The tm structure contains fields that are easy to confuse (year offset by 1900, months starting from 0).
  • Lack of support for time zones and time intervals.


2. Modern C++: The chrono Library (C++11 and later)



The chrono library is a powerful and type-safe tool for working with time. It forms the basis of all modern C++ projects.



Main components:

  • Clocks: system_clock (system time), steady_clock (monotonic clock for measurements), high_resolution_clock (maximum resolution).
  • Time points: tied to specific clocks.
  • Durations: time intervals (seconds, milliseconds, nanoseconds).


#include <iostream>#include <chrono>#include <thread>

int main() { using namespace std::chrono;

// Current time point auto now = system_clock::now();

// Convert to time_t for display std::time_t now_c = system_clock::to_time_t(now); std::cout << "Current time: " << std::ctime(&now_c);

// Measure execution time auto start = steady_clock::now(); std::this_thread::sleep_for(milliseconds(500)); // simulate work auto end = steady_clock::now();

auto duration = duration_cast<milliseconds>(end - start); std::cout << "Elapsed: " << duration.count() << " ms" << std::endl;

return 0;}


Advantages of chrono:

  • High precision (nanoseconds).
  • Type safety (you cannot accidentally add seconds and milliseconds).
  • Support for arithmetic (addition/subtraction of durations and time points).
  • Built-in support for various time units.
  • Thread safety.


3. Formatting Dates and Time (C++20)



With the C++20 standard, working with dates and time has become even more convenient thanks to the new formatting functions based on std::format.



#include <iostream>#include <chrono>#include <format>

int main() { auto now = std::chrono::system_clock::now(); std::cout << std::format("Current date and time: {:%Y-%m-%d %H:%M:%S}", now) << std::endl; return 0;}


Format specifiers:

  • %Y — year (4 digits)
  • %m — month (01-12)
  • %d — day (01-31)
  • %H — hours (00-23)
  • %M — minutes (00-59)
  • %S — seconds (00-59)


4. Parsing Dates and Time



Parsing strings into time points is a common task. In C++20, this can be done using std::chrono::parse.



#include <iostream>#include <chrono>#include <sstream>

int main() { std::string date_str = "2024-03-15 14:30:00"; std::chrono::sys_time<std::chrono::seconds> tp; std::istringstream iss(date_str); iss >> std::chrono::parse("%Y-%m-%d %H:%M:%S", tp); if (iss) { std::cout << "Parsed successfully: " << tp << std::endl; } else { std::cout << "Parse error" << std::endl; } return 0;}


5. Timers and Delays



Timers are an important part of many applications. In C++, you can implement timers using std::thread and std::chrono.



#include <iostream>#include <chrono>#include <thread>#include <functional>

class Timer {private: std::thread thread; bool running = false;

public: void start(int interval_ms, std::function<void()> callback) { running = true; thread = std::thread([this, interval_ms, callback]() { while (running) { std::this_thread::sleep_for(std::chrono::milliseconds(interval_ms)); callback(); } }); }

void stop() { running = false; if (thread.joinable()) { thread.join(); } }

~Timer() { stop(); }};

int main() { Timer timer; timer.start(1000, []() { std::cout << "Timer tick: " << std::chrono::system_clock::now() << std::endl; });

std::this_thread::sleep_for(std::chrono::seconds(5)); timer.stop();

return 0;}


6. Working with Time Zones (C++20)



C++20 introduced full support for time zones through the <chrono> library.



#include <iostream>#include <chrono>#include <format>

int main() { using namespace std::chrono;

auto now = system_clock::now(); // Convert to a specific time zone auto ny_time = zoned_time{"America/New_York", now}; auto london_time = zoned_time{"Europe/London", now}; std::cout << "New York: " << std::format("{:%Y-%m-%d %H:%M:%S}", ny_time) << std::endl; std::cout << "London: " << std::format("{:%Y-%m-%d %H:%M:%S}", london_time) << std::endl; return 0;}


Conclusion



Working with dates and time in C++ has come a long way from the cumbersome C functions to the powerful and convenient chrono library. Modern C++ provides everything you need: high-precision clocks, type-safe durations, convenient formatting and parsing, time zone support, and much more. Use the classic time_t approach only for maintaining legacy code; for new projects, always prefer chrono.



Useful links:

Blogs

Book Recommendations