Fusos horários em C++: como parar de se confundir com os fusos horários

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

Por que o tempo é uma dor (e como C++ pode ajudar)

\n

Imagine: seu servidor processa pedidos de Nova York, Londres e Tóquio. Você registra a hora de criação do pedido em UTC e depois mostra ao usuário: "Seu pedido foi criado às 03:15". Para um morador de Nova York, são 22:15 do dia anterior; para um londrino, são 04:15 da manhã; e o morador de Tóquio vai acordar com uma notificação no meio da noite. Um problema clássico que transforma um simples log em um quebra-cabeça.

\n

Em C++, por muito tempo não houve uma forma padrão adequada para trabalhar com fusos horários. Os desenvolvedores ou sofriam com time_t e struct tm, ou usavam bibliotecas pesadas como Boost.DateTime. Mas com a chegada do C++20, a situação mudou drasticamente. A biblioteca std::chrono ganhou suporte completo para fusos horários. E embora muitos compiladores ainda estejam se atualizando para o padrão, vamos ver como já hoje escrever código limpo e portável para trabalhar com fusos horários em C++.

\n

Neste artigo, mostrarei como transformar o caos dos fusos horários em um sistema organizado com C++. Você aprenderá a trabalhar com std::chrono::tzdb, converter UTC para hora local, considerar o horário de verão e evitar erros comuns.

\n\n

Fundamentos: o que é um fuso horário em C++ do ponto de vista do chrono

\n

Em C++20, um fuso horário não é apenas um deslocamento em horas em relação ao UTC. É um objeto completo que conhece o histórico de mudanças de horário na região: quando os relógios foram adiantados/atrasados, quando o horário de verão foi abolido e quais regras estão em vigor. Todas essas informações são armazenadas no banco de dados de fusos horários (tzdb), que está embutido na biblioteca padrão.

\n\n

Tipos principais para trabalhar com fusos horários

\n

Para não se confundir, lembre-se de três tipos principais:

\n
    \n
  • std::chrono::time_zone — representa um fuso horário específico (por exemplo, "America/New_York").
  • \n
  • std::chrono::zoned_time — uma combinação de "fuso horário + instante no tempo". Este é o tipo mais conveniente para armazenar e exibir o horário considerando o fuso.
  • \n
  • std::chrono::time_zone_link — nomes alternativos para zonas (por exemplo, "US/Eastern" pode ser um link para "America/New_York").
  • \n
\n\n

Obtendo a lista de todos os fusos horários

\n

Vamos começar com algo simples: exibir todos os fusos horários disponíveis. Isso é útil quando você permite que o usuário escolha seu fuso horário.

\n\n
#include <iostream>\n#include <chrono>\n#include <string>\n\nint main() {\n    // Obtém acesso ao banco de dados de fusos horários\n    const auto& tzdb = std::chrono::get_tzdb();\n    \n    // Exibe os nomes de todas as zonas\n    std::cout << "Fusos horários disponíveis (" << tzdb.zones.size() << "):\\n";\n    for (const auto& zone : tzdb.zones) {\n        std::cout << zone.name() << '\\n';\n    }\n    return 0;\n}
\n\n

Observe: get_tzdb() retorna uma referência constante. O banco de dados é carregado uma vez na primeira chamada e é armazenado em cache. Isso significa que você pode chamar essa função de diferentes partes do programa sem medo — a sobrecarga ocorre apenas na primeira chamada.

\n\n

Conversão de horário entre fusos horários em C++

\n

Agora vamos ao que interessa: a conversão. Suponha que você tenha um horário em UTC e queira mostrá-lo ao usuário no fuso local dele. Ou o contrário: o usuário insere uma data no horário dele, e você precisa salvá-la em UTC.

\n\n

De UTC para horário local

\n

Cenário: o servidor recebeu o horário de um evento em UTC (por exemplo, 2024-12-01 15:30:00 UTC). Precisa mostrá-lo para o fuso "Europe/Moscow".

\n\n
#include <iostream>\n#include <chrono>\n#include <format> // C++20 para formatação\n\nint main() {\n    using namespace std::chrono;\n    \n    // 1. Cria um instante no tempo em UTC\n    // 2024-12-01 15:30:00 UTC\n    auto tp = sys_days{December / 1 / 2024} + 15h + 30min;\n                

Blogs

Book Recommendations