Trabajo con fechas y horas en C++: de la A a la Z
Trabajar con fechas y horas es una de las tareas básicas en programación. Se necesita en todas partes: desde el registro de eventos hasta el cálculo de plazos y la creación de gráficos. En C++, históricamente esta área no era la más conveniente, pero con la llegada del estándar C++11 y versiones posteriores (C++14, C++17, C++20) la situación cambió drásticamente. En este artículo, analizaremos todos los aspectos clave: desde las funciones clásicas de C hasta la biblioteca moderna chrono, temporizadores, formato y análisis sintáctico. El material será útil tanto para principiantes como para desarrolladores experimentados que deseen sistematizar sus conocimientos.
1. Enfoque clásico: time_t y la estructura tm
Antes de la aparición de chrono, la herramienta principal eran las funciones de <ctime>. Este enfoque sigue siendo relevante para mantener código antiguo y para tareas simples.
Funciones principales:
time()— devuelve la hora actual comotime_t(número de segundos desde el 1 de enero de 1970).localtime()— conviertetime_ten una estructuratm(hora local).gmtime()— convierte a UTC.strftime()— formateatmen una cadena.mktime()— conversión inversa:tm→time_t.
#include <iostream>#include <ctime>
int main() { // Obtenemos la hora actual std::time_t now = std::time(nullptr);
// Convertimos a hora local std::tm* local_tm = std::localtime(&now);
// Formateamos en una cadena char buffer[80]; std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", local_tm);
std::cout << "Hora actual: " << buffer << std::endl; return 0;}Desventajas del enfoque:
- Solo funciona con segundos (milisegundos y microsegundos no están disponibles).
- No es seguro en entornos multiproceso (use
localtime_ren POSIX). - La estructura
tmcontiene campos que son fáciles de confundir (el año está desplazado en 1900, los meses comienzan en 0). - Falta soporte para zonas horarias e intervalos de tiempo.
2. C++ moderno: la biblioteca chrono (C++11 y posteriores)
La biblioteca chrono es una herramienta potente y type-safe para trabajar con el tiempo. Es la base de todos los proyectos modernos de C++.
Componentes principales:
- Relojes (clocks):
system_clock(hora del sistema),steady_clock(reloj monótono para mediciones),high_resolution_clock(máxima resolución). - Puntos en el tiempo (time_point): vinculados a un reloj específico.
- Duraciones (duration): intervalos de tiempo (segundos, milisegundos, nanosegundos).
#include <iostream>#include <chrono>#include <thread>
int main() { using namespace std::chrono;
// Momento actual en el tiempo auto now = system_clock::now();
// Convertimos a time_t para mostrar std::time_t now_c = system_clock::to_time_t(now); std::cout << "Hora actual: " << std::ctime(&now_c);
// Medición del tiempo de ejecución auto start = steady_clock::now(); std::this_thread::sleep_for(milliseconds(500)); // simulación de trabajo auto end = steady_clock::now();
auto duration = duration_cast<milliseconds>(end - start); std::cout << "Transcurrido: " << duration.count() << " ms" << std::endl;
return 0;}Ventajas de chrono:
- Alta precisión (nanosegundos).
- Type-safety (no se pueden sumar accidentalmente segundos con milisegundos).
- Soporte para aritmética (suma/resta