Trabalho com datas e horas em C++: guia completo

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Trabalho com datas e horas em C++: do clássico ao padrão moderno



Gerenciar datas e horas é uma das tarefas essenciais no desenvolvimento de software. Seja para registro de eventos, cálculo de prazos, trabalho com temporizadores ou análise de dados — não é possível prescindir de ferramentas confiáveis. Em C++, existem várias abordagens para isso: desde a biblioteca clássica <ctime> até a moderna <chrono>, que surgiu no C++11 e foi significativamente expandida no C++20. Neste artigo, vamos analisar os principais métodos de trabalho com datas e horas, fornecer exemplos práticos e mostrar como evitar erros típicos.



1. Abordagem clássica: biblioteca <ctime>



A biblioteca <ctime> veio para o C++ da linguagem C. Ela fornece meios simples, porém limitados, para trabalhar com tempo calendário. Os tipos principais são: std::time_t (número inteiro de segundos desde 1º de janeiro de 1970) e std::tm (estrutura com campos ano, mês, dia, horas, minutos, segundos, etc.).



Exemplo 1: Obtendo a hora atual e formatando



#include <iostream>#include <ctime>

int main() { // Obtém a hora atual std::time_t now = std::time(nullptr); // Converte para hora local std::tm* local = std::localtime(&now); // Exibe no formato "AAAA-MM-DD HH:MM:SS" char buffer[80]; std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", local); std::cout << "Hora atual: " << buffer << std::endl; return 0;}


Funções principais de <ctime>:

  • std::time() — retorna a hora calendário atual.
  • std::localtime() — converte time_t em uma estrutura tm, representando a hora local.
  • std::gmtime() — o mesmo, mas para UTC (Tempo Universal Coordenado).
  • std::mktime() — conversão inversa: de tm para time_t.
  • std::difftime() — calcula a diferença em segundos entre dois momentos no tempo.
  • std::strftime() — formata data e hora em uma string de acordo com um modelo especificado.


Desvantagens: a biblioteca não considera fusos horários (exceto local e UTC), não suporta alta precisão (apenas segundos), e a estrutura tm não é type-safe (por exemplo, o ano é contado a partir de 1900, o mês de 0 a 11).



2. Padrão moderno: biblioteca <chrono> (C++11 e posteriores)



A partir do C++11, a biblioteca padrão foi complementada com <chrono> — uma biblioteca type-safe e de alta precisão para trabalhar com tempo. Ela opera com três conceitos principais: duração (duration), ponto no tempo (time_point) e relógio (clock).



Tipos de relógio:

  • std::chrono::system_clock — hora do sistema, vinculada ao calendário (pode ser convertida para time_t).
  • std::chrono::steady_clock — relógio monotônico, ideal para medir intervalos (não está sujeito a ajustes).
  • std::chrono::high_resolution_clock — relógio com a maior resolução disponível (frequentemente é sinônimo de steady_clock).


Exemplo 2: Medindo o tempo de execução de uma operação



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

int main() { // Marca o início auto start = std::chrono::steady_clock::now(); // Simula trabalho std::this_thread::sleep_for(std::chrono::milliseconds(500)); // Marca o fim auto end = std::chrono::steady_clock::now(); // Calcula a diferença auto duration = end - start; // Exibe a duração em milissegundos std::cout << "Tempo de execução: " << std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() << " ms" << std::endl; return 0;}


Exemplo 3: Trabalhando com system_clock e calendário (C++20)



Com o C++20, a biblioteca <chrono> ganhou suporte completo para calendário e fusos horários. Agora é possível criar datas, adicionar dias e trabalhar com fusos horários de forma segura.



#include <iostream>#include <chrono>

int main() { using namespace std::chrono; // Cria uma data: 15 de março de 2024 year_month_day data = March/15/2024; // Adiciona 7 dias auto nova_data = sys_days{data} + days(7); // Converte de volta para year_month_day year_month_day resultado = nova_data; std::cout << "Data original: " << data << std::endl; std::cout << "Data após 7 dias: " << resultado << std::endl; return 0;}


Vantagens do <chrono>:

  • Type safety — impossível misturar unidades (horas com segundos) sem conversão explícita.
  • Alta precisão — suporta nanossegundos, microssegundos, etc.
  • Suporte a fusos horários e calendário (C++20).
  • Relógios monotônicos para medições precisas de intervalos.


3. Erros comuns e como evitá-los



Erro 1: Ignorar a natureza monotônica do steady_clock

O std::chrono::steady_clock não pode ser convertido para time_t ou para uma data calendário. Use system_clock para obter a hora atual do calendário.



Erro 2: Usar time() para medir intervalos

A função std::time() tem precisão de apenas um segundo. Para medições de alta precisão, use std::chrono::steady_clock.



Erro 3: Ignorar a localidade ao formatar datas

A função std::strftime() usa a localidade atual. Se você precisa de um formato específico independente da localidade, use <chrono> com C++20 ou formate manualmente.



4. Quando usar qual abordagem?



  • <ctime> — adequado para tarefas simples onde apenas segundos são necessários e a compatibilidade com código C legado é importante.
  • <chrono> (C++11/14/17) — a melhor escolha para novos projetos que exigem alta precisão e type safety.
  • <chrono> (C++20) — indispensável se você precisa de suporte completo a calendário e fusos horários.


Dominar o trabalho com tempo em C++ permite escrever código mais confiável e portável. A biblioteca <chrono> oferece ferramentas poderosas que tornam o código mais expressivo e seguro. Recomendamos usá-la em novos projetos, recorrendo ao <ctime> apenas quando necessário para compatibilidade.

Blogs

Book Recommendations