Работа с датами и временем в C++: от А до Я — полное руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с датами и временем в C++: от А до Я

Работа с датами и временем — одна из базовых задач в программировании. Она требуется везде: от логирования событий до расчёта дедлайнов и построения графиков. В C++ исторически эта область была не самой удобной, но с приходом стандарта C++11 и последующих версий (C++14, C++17, C++20) ситуация кардинально изменилась. В этой статье мы разберём все ключевые аспекты: от классических C-функций до современной библиотеки chrono, таймеров, форматирования и парсинга. Материал будет полезен как новичкам, так и опытным разработчикам, желающим систематизировать знания.

1. Классический подход: time_t и структура tm

До появления chrono основным инструментом были функции из <ctime>. Этот подход остаётся актуальным для поддержки старого кода и простых задач.

Основные функции:

  • time() — возвращает текущее время как time_t (количество секунд с 1 января 1970 года).
  • localtime() — преобразует time_t в структуру tm (локальное время).
  • gmtime() — преобразует в UTC.
  • strftime() — форматирует tm в строку.
  • mktime() — обратное преобразование: tm → time_t.
#include <iostream>
#include <ctime>

int main() {
    // Получаем текущее время
    std::time_t now = std::time(nullptr);

    // Преобразуем в локальное время
    std::tm* local_tm = std::localtime(&now);

    // Форматируем в строку
    char buffer[80];
    std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", local_tm);

    std::cout << "Текущее время: " << buffer << std::endl;
    return 0;
}

Минусы подхода:

  • Работает только с секундами (миллисекунды и микросекунды недоступны).
  • Небезопасно в многопоточных средах (используйте localtime_r в POSIX).
  • Структура tm содержит поля, которые легко перепутать (год сдвинут на 1900, месяцы с 0).
  • Отсутствует поддержка часовых поясов и интервалов времени.

2. Современный C++: библиотека chrono (C++11 и новее)

Библиотека chrono — это мощный и типобезопасный инструмент для работы со временем. Она лежит в основе всех современных C++ проектов.

Основные компоненты:

  • Часы (clocks): system_clock (системное время), steady_clock (монотонные часы для замеров), high_resolution_clock (максимальное разрешение).
  • Моменты времени (time_point): привязаны к конкретным часам.
  • Длительности (duration): интервалы времени (секунды, миллисекунды, наносекунды).
#include <iostream>
#include <chrono>
#include <thread>

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

    // Текущий момент времени
    auto now = system_clock::now();

    // Преобразуем в time_t для отображения
    std::time_t now_c = system_clock::to_time_t(now);
    std::cout << "Текущее время: " << std::ctime(&now_c);

    // Замер времени выполнения
    auto start = steady_clock::now();
    std::this_thread::sleep_for(milliseconds(500)); // имитация работы
    auto end = steady_clock::now();

    auto duration = duration_cast<milliseconds>(end - start);
    std::cout << "Прошло: " << duration.count() << " мс" << std::endl;

    return 0;
}

Преимущества chrono:

  • Высокая точность (наносекунды).
  • Типобезопасность (нельзя случайно сложить секунды с миллисекундами).
  • Поддержка арифметики (сложение/вычитание длительностей).
  • Удобные литералы: 5s, 100ms, 1h (требуется C++14).
  • Работает в многопоточных приложениях без дополнительных усилий.

3. Форматирование и парсинг дат в C++20

Стандарт C++20 добавил долгожданные возможности форматирования дат и времени, а также парсинга из строк. Основной инструмент — std::format (из <format>) и расширения для chrono.

Форматирование:

#include <iostream>
#include <chrono>
#include <format> // C++20

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

    auto now = system_clock::now();
    // Форматируем с помощью std::format
    std::cout << std::format("Текущее время: {:%Y-%m-%d %H:%M:%S}", now) << std::endl;

    // Можно указать часовой пояс
    auto tz = current_zone(); // из <chrono>
    std::cout << std::format("Время в Москве: {:%Y-%m-%d %H:%M:%S %Z}", 
                              zoned_time{tz, now}) << std::endl;

    return 0;
}

Парсинг даты из строки:

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

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

    std::string input = "2024-12-31 23:59:59";
    std::istringstream iss(input);

    sys_seconds tp;
    std::chrono::from_stream(iss, "%Y-%m-%d %                

Блоги

Рекомендаций по книгам