Работа с датами в C++: обзор современных библиотек
Работа с датами и временем — одна из ключевых задач в разработке программного обеспечения. В C++ долгое время не было удобного стандартного инструментария, что приводило к использованию C-функций (ctime, localtime) или сторонних решений. Однако с приходом стандарта C++11 и последующих версий ситуация кардинально изменилась. В этой статье мы рассмотрим три основных подхода к работе с датами в C++: стандартную библиотеку std::chrono, расширение date.h от Говарда Хиннанта (Howard Hinnant) и мощный фреймворк Boost.DateTime.
1. Стандартная библиотека std::chrono (C++11 и новее)
std::chrono — это часть стандартной библиотеки C++, предоставляющая типы для представления временных точек (time_point), длительностей (duration) и часов (clock). Она идеально подходит для измерения интервалов времени, работы с таймерами и высокоточными задержками. Однако до C++20 в ней не было удобных средств для работы с календарными датами (день, месяц, год).
Пример: измерение времени выполнения кода
#include <iostream>
#include <chrono>
#include <thread>
int main() {
auto start = std::chrono::high_resolution_clock::now();
// Имитация работы
std::this_thread::sleep_for(std::chrono::milliseconds(500));
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "Время выполнения: " << duration.count() << " мс\n";
return 0;
}
С C++20 в std::chrono появилась поддержка календаря: типы year, month, day, year_month_day и операторы для работы с ними. Теперь можно писать:
#include <chrono>
#include <iostream>
int main() {
using namespace std::chrono;
auto today = floor<days>(system_clock::now());
year_month_day ymd{today};
std::cout << int(ymd.year()) << "-"
<< unsigned(ymd.month()) << "-"
<< unsigned(ymd.day()) << "\n";
return 0;
}
2. Библиотека date.h (Howard Hinnant)
До выхода C++20 разработчики активно использовали библиотеку date.h — однофайловое расширение для std::chrono, написанное Говардом Хиннантом. Она предоставляет полный набор функций для работы с датами: парсинг, форматирование, вычисление разницы между датами, работа с часовыми поясами и даже поддержка юлианского календаря.
Пример: парсинг строки в дату
#include "date.h"
#include <iostream>
#include <sstream>
int main() {
std::istringstream ss("2025-04-07");
date::sys_days tp;
ss >> date::parse("%F", tp); // Формат ISO 8601
auto ymd = date::year_month_day{tp};
std::cout << "Год: " << int(ymd.year()) << "\n";
return 0;
}
Пример: вычисление возраста
#include "date.h"
#include <iostream>
int main() {
using namespace date;
auto birth = sys_days{year{1990}/month{1}/day{15}};
auto today = floor<days>(std::chrono::system_clock::now());
auto age = today - birth;
std::cout << "Возраст в днях: " << age.count() << "\n";
// Возраст в годах (приблизительно)
auto years = duration_cast<std::chrono::years>(age);
std::cout << "Возраст в годах: " << years.count() << "\n";
return 0;
}
Библиотека date.h легко подключается (достаточно скопировать заголовочный файл) и не требует сборки. Она стала основой для стандартного std::chrono в C++20, поэтому код на ней легко портируется.
3. Boost.DateTime
Boost.DateTime — это часть библиотеки Boost, которая предоставляет обширные возможности для работы с датами, временем, часовыми поясами и календарями. Она поддерживает григорианский, юлианский и другие календари, а также позволяет вычислять даты праздников (например,