Zonas horarias en C++: cómo dejar de confundirse con los husos horarios

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Por qué el tiempo es un dolor (y cómo C++ puede ayudar)

\n

Imagine: su servidor procesa pedidos de Nueva York, Londres y Tokio. Usted registra la hora de creación del pedido en UTC y luego se la muestra al usuario: «Su pedido fue creado a las 03:15». Para un neoyorquino son las 22:15 del día anterior, para un londinense las 04:15 de la mañana, y un tokiota se despertará con una notificación en mitad de la noche. Un problema clásico que convierte un simple registro en un rompecabezas.

\n

En C++, durante mucho tiempo no hubo una forma estándar adecuada de trabajar con zonas horarias. Los desarrolladores sufrían con time_t y struct tm, o recurrían a bibliotecas pesadas como Boost.DateTime. Pero con la llegada de C++20 la situación cambió drásticamente. La biblioteca std::chrono incorporó soporte completo para husos horarios. Y aunque muchos compiladores aún están alcanzando el estándar, veremos cómo escribir hoy mismo código limpio y portátil para trabajar con zonas horarias en C++.

\n

En este artículo, le mostraré cómo convertir el caos de los husos horarios en un sistema ordenado con C++. Aprenderá a trabajar con std::chrono::tzdb, convertir UTC a hora local, tener en cuenta el horario de verano y evitar errores típicos.

\n\n

Fundamentos: qué es una zona horaria en C++ desde la perspectiva de chrono

\n

En C++20, una zona horaria no es solo un desplazamiento en horas respecto a UTC. Es un objeto completo que conoce la historia de los cambios de hora en una región: cuándo se adelantaron los relojes, cuándo se canceló el cambio al horario de verano y qué reglas están vigentes. Toda esta información se almacena en la base de datos de zonas horarias (tzdb), que está integrada en la biblioteca estándar.

\n\n

Tipos clave para trabajar con zonas horarias

\n

Para no confundirse, recuerde estos tres tipos principales:

\n
    \n
  • std::chrono::time_zone — representa una zona horaria específica (por ejemplo, "America/New_York").
  • \n
  • std::chrono::zoned_time — un par «zona horaria + instante de tiempo». Es el tipo más conveniente para almacenar y mostrar la hora teniendo en cuenta la zona.
  • \n
  • std::chrono::time_zone_link — nombres alternativos de zonas (por ejemplo, "US/Eastern" puede ser un enlace a "America/New_York").
  • \n
\n\n

Obtenemos la lista de todas las zonas horarias

\n

Empecemos con algo simple: mostrar todas las zonas horarias disponibles. Esto es útil cuando le da al usuario la opción de elegir su huso horario.

\n\n
#include <iostream>\n#include <chrono>\n#include <string>\n\nint main() {\n    // Accedemos a la base de datos de zonas horarias\n    const auto& tzdb = std::chrono::get_tzdb();\n    \n    // Mostramos los nombres de todas las zonas\n    std::cout << "Zonas horarias disponibles (" << tzdb.zones.size() << "):\\n";\n    for (const auto& zone : tzdb.zones) {\n        std::cout << zone.name() << '\\n';\n    }\n    return 0;\n}
\n\n

Tenga en cuenta: get_tzdb() devuelve una referencia constante. La base de datos se carga una sola vez en la primera llamada y se almacena en caché. Esto significa que puede llamar a esta función desde diferentes partes del programa sin problema: la sobrecarga solo ocurrirá en la primera llamada.

\n\n

Conversión de hora entre zonas horarias en C++

\n

Ahora pasemos a lo más importante: la conversión. Supongamos que tiene una hora en UTC y quiere mostrársela al usuario en su zona local. O viceversa: el usuario ingresa una fecha en su hora local y usted necesita guardarla en UTC.

\n\n

De UTC a hora local

\n

Escenario: el servidor recibió la hora de un evento en UTC (por ejemplo, 2024-12-01 15:30:00 UTC). Necesita mostrarla para la zona "Europe/Moscow".

\n\n
#include <iostream>\n#include <chrono>\n#include <format> // C++20 para formateo\n\nint main() {\n    using namespace std::chrono;\n    \n    // 1. Creamos un instante de tiempo en UTC\n    // 2024-12-01 15:30:00 UTC\n    auto tp = sys_days{December / 1 / 2024} + 15h + 30min;\n                

Blogs

Book Recommendations