Trabalho com datas em C++: visão geral das bibliotecas modernas
Trabalhar com datas e horas é uma das tarefas essenciais no desenvolvimento de software. Em C++, por muito tempo, não houve um conjunto de ferramentas padrão conveniente, o que levava ao uso de funções C (ctime, localtime) ou soluções de terceiros. No entanto, com a chegada do padrão C++11 e versões posteriores, a situação mudou drasticamente. Neste artigo, examinaremos três abordagens principais para trabalhar com datas em C++: a biblioteca padrão std::chrono, a extensão date.h de Howard Hinnant e o poderoso framework Boost.DateTime.
1. Biblioteca padrão std::chrono (C++11 e posteriores)
std::chrono faz parte da biblioteca padrão C++, fornecendo tipos para representar pontos no tempo (time_point), durações (duration) e relógios (clock). É ideal para medir intervalos de tempo, trabalhar com temporizadores e atrasos de alta precisão. No entanto, até o C++20, não possuía meios convenientes para trabalhar com datas de calendário (dia, mês, ano).
Exemplo: medindo o tempo de execução do código
#include <iostream>#include <chrono>#include <thread>
int main() { auto start = std::chrono::high_resolution_clock::now();
// Simulação de trabalho 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 << "Tempo de execução: " << duration.count() << " ms"; return 0;}Com o C++20, o std::chrono ganhou suporte para calendário: os tipos year, month, day, year_month_day e operadores para trabalhar com eles. Agora é possível escrever:
#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()) << ""; return 0;}2. Biblioteca date.h (Howard Hinnant)
Antes do lançamento do C++20, os desenvolvedores usavam ativamente a biblioteca date.h — uma extensão de arquivo único para std::chrono, escrita por Howard Hinnant. Ela fornece um conjunto completo de funções para trabalhar com datas: parsing, formatação, cálculo de diferenças entre datas, trabalho com fusos horários e até suporte para o calendário juliano.
Exemplo: parsing de uma string para data
#include "date.h"#include <iostream>#include <sstream>
int main() { std::istringstream ss("2025-04-07"); date::sys_days tp; ss >> date::parse("%F", tp); // Formato ISO 8601 auto ymd = date::year_month_day{tp}; std::cout << "Ano: " << int(ymd.year()) << ""; return 0;}Exemplo: cálculo de idade
#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 << "Idade em dias: " << age.count() << ""; // Idade em anos (aproximadamente) auto years = duration_cast<std::chrono::years>(age); std::cout << "Idade em anos: " << years.count() << ""; return 0;}A biblioteca date.h é facilmente incluída (basta copiar o arquivo de cabeçalho) e não requer compilação. Ela serviu de base para o std::chrono padrão no C++2