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

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

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

Начать курс

Работа с датами и временем в C++: от <ctime> до современного <chrono>

Работа с датами и временем — одна из ключевых задач в любом серьёзном приложении: от логов и бэкапов до таймеров и финансовых расчётов. В C++ исторически сложилось два подхода: классический C-стиль через заголовочный файл <ctime> и современный, типобезопасный подход через библиотеку <chrono>, появившуюся в C++11 и значительно расширенную в C++20. В этой статье мы разберём оба метода, научимся получать текущее время, измерять интервалы, форматировать даты и избегать типичных ошибок.

1. Классический способ: <ctime> и std::time_t

До C++11 единственным стандартным способом работы со временем были функции из C: time(), localtime(), strftime(). Этот подход до сих пор используется в легаси-коде и простых задачах.

Получение текущего времени

Функция std::time(nullptr) возвращает количество секунд с 1 января 1970 года (Unix-эпоха) в виде целого числа std::time_t.

#include <iostream>
#include <ctime>

int main() {
    std::time_t now = std::time(nullptr);
    std::cout << "Текущее время (сек с эпохи): " << now << std::endl;
    return 0;
}

Преобразование в читаемый формат

Чтобы получить структуру с компонентами (год, месяц, день, часы и т.д.), используйте std::localtime() или std::gmtime().

#include <iostream>
#include <ctime>

int main() {
    std::time_t now = std::time(nullptr);
    std::tm* local = std::localtime(&now);

    std::cout << "Год: " << (local->tm_year + 1900) << std::endl;
    std::cout << "Месяц: " << (local->tm_mon + 1) << std::endl;
    std::cout << "День: " << local->tm_mday << std::endl;
    return 0;
}

Форматирование строки с strftime

Функция std::strftime() позволяет гибко отформатировать дату в строку по заданному шаблону.

#include <iostream>
#include <ctime>

int main() {
    std::time_t now = std::time(nullptr);
    std::tm* local = std::localtime(&now);

    char buffer[80];
    std::strftime(buffer, sizeof(buffer), "%d.%m.%Y %H:%M:%S", local);
    std::cout << "Текущая дата и время: " << buffer << std::endl;
    return 0;
}

⚠️ Важно: std::localtime() и std::gmtime() возвращают указатель на статический буфер — это не потокобезопасно. В C++11 появились реентерабельные версии localtime_s (Windows) или localtime_r (POSIX).

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

Библиотека <chrono> предлагает строгую типизацию, работу с разными единицами времени и высокую точность. Основные компоненты:

  • Часы (clocks): system_clock, steady_clock, high_resolution_clock
  • Моменты времени (time_point): привязка к конкретному моменту
  • Длительности (duration): интервалы времени (секунды, миллисекунды и т.д.)

Получение текущего момента

#include <iostream>
#include <chrono>
#include <ctime> // для std::time_t

int main() {
    auto now = std::chrono::system_clock::now();
    std::time_t now_time = std::chrono::system_clock::to_time_t(now);
    std::cout << "Текущее время: " << std::ctime(&now_time);
    return 0;
}

Измерение интервалов времени (таймер)

Одна из самых частых задач — замерить время выполнения кода. Для этого идеально подходит std::chrono::steady_clock (монотонные часы, не подвержены корректировкам).

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

int main() {
    auto start = std::chrono::steady_clock::now();

    // Имитация работы
    std::this_thread::sleep_for(std::chrono::milliseconds(500));

    auto end = std::chrono::steady_clock::now();
    auto diff = end - start;

    std::cout << "Прошло: "
              << std::chrono::duration_cast<std::chrono::milliseconds>(diff).count()
              << " мс" << std::endl;
    return 0;
}

Работа с длительностями

Библиотека поддерживает все стандартные единицы: nanoseconds, microseconds, milliseconds, seconds, minutes, hours (и даже days с C++20).

#include <iostream>
#include <chrono>

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

    auto duration = 2h + 30min + 15s; // 2 часа 30 минут 15 секунд
    auto total_sec = std::chrono::duration_cast<std::chrono::seconds>(duration);

    std::cout << "Всего секунд: " << total_sec.count() << std::endl;
    return 0;
}

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

Начиная с C++20, в <chrono

Блоги

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