Puede haber tantas maneras de representar fechas como el número de países o de
idiomas. Algunas de las abreviaciones más ampliamente usadas son
dd-mm-yy
, mm-dd-yy
, yy-mm-dd
.
Hay varios ámbitos en los cuales es importante que se puedan interpretar fechas
y horas sin ambigüedad; para este fin existe el estándar ISO 86011 con
formato YYYY-MM-DD
, aplicable para representar fechas del calendario
gregoriano. Este estándar también incluye la representación de hora,
extendiéndola a YYYY-MM-DD HH:mm:ss
. También se puede usar la representación
de hora local poniendo la letra T
entre la fecha y la hora. Adicionalmente se
puede representar la zona horaria UTC: hora local relativa a la UTC (Tiempo
Universal Coordinado).
En total YYYY-MM-DDTHH:mm:ss Z
corresponde a 2021-04-15T18:20:28-0500
donde
año: 2021, mes: 04, día: 15, T: hora local, 18 horas (6 p.m.), 20 minutos,
28 segundos, con UTC: -0500.
Este formato incluye otros campos y aspectos adicionales no analizados acá.
Usando iostreams
Como casi todo en C++, hay múltiples maneras de resolver una tarea.
La forma tradicional es usar iostreams
con std::put_time
para la
visualización.
Para obtener los valores con std::time
al estilo C:
#include <ctime> // Para std::time
#include <iomanip> // Para std::put_time
#include <iostream>
int main()
{
const std::time_t now_time_t = std::time(nullptr);
const std::tm now_tm = *(std::localtime(&now_time_t));
std::cout << std::put_time(&now_tm, "%Y-%m-%dT%T%z");
return 0;
}
O con std::chrono::system_clock
al estilo C++:
#include <chrono>
#include <iomanip>
#include <iostream>
using std::chrono::system_clock;
int main()
{
const std::time_t now_time_t = system_clock::to_time_t(system_clock::now());
const std::tm now_tm = *(std::localtime(&now_time_t));
std::cout << std::put_time(&now_tm, "%Y-%m-%dT%T%z");
return 0;
}
Donde la representación "%Y-%m-%d T %T%z"
corresponde a YYYY-MM-DD T HH:mm:ss Z
según los especificadores de std::put_time
2.
std::put_time | ISO 8601 |
---|---|
%Y | YYYY |
%m | MM |
%d | DD |
%T | HH:mm:ss |
%z | Z |
Usando la biblioteca {fmt}
Una forma interesante de hacer esta misma representación es usar la biblioteca
fmt
(usando Conan como administrador de paquetes
) para poder hacer una manipulación thread-safe
y más robusta.
Con std::time
:
#include <fmt/chrono.h>
int main()
{
const std::time_t now = std::time(nullptr);
fmt::print("{:%Y-%m-%dT%H:%M:%S%z}\n", fmt::localtime(now));
return 0;
}
Con std::chrono::system_clock
y fmt se puede usar directamente
std::chrono::time_point
por lo cual no hace falta convertir el objeto a
std::time_t
; incluso se genera un binario de menor tamaño.
#include <fmt/chrono.h>
using std::chrono::system_clock;
int main()
{
fmt::print("{0:%Y-%m-%d}T{0:%H:%M:%S%z}\n",
fmt::localtime(system_clock::now()));
return 0;
}
En todos los casos el posible resultado, teniendo en cuenta la zona horaria (UTC-5), es:
2021-04-15T18:20:28-0500
Hora con mili segundos
Obtener los milisegundos con std::time_t
es complejo y no vale la pena
analizarlo ahora mismo; con std::chrono::time_point
es un poco menos complejo:
#include <fmt/chrono.h>
using std::chrono::duration_cast;
using std::chrono::milliseconds;
using std::chrono::system_clock;
using std::chrono::time_point;
int main()
{
const time_point<system_clock> time_now = system_clock::now();
const auto now_ms = (duration_cast<milliseconds>(time_now.time_since_epoch()) % 1000).count();
fmt::print("{0:%Y-%m-%dT%H:%M:%S}.{1}{0:%z}\n", fmt::localtime(time_now), now_ms);
return 0;
}
Obteniendo:
2021-04-15T18:20:28.157-0500
La biblioteca spdlog
Es una biblioteca de registro de mensajes con un desempeño sobresaliente.
Internamente usa a fmt
y por defecto muestra los mensajes de registro con
la fecha-hora en el formato ISO_8601. En este ejemplo se usa la referencia a la
receta de conan spdlog/1.8.2
, y su uso es el siguiente:
#include <spdlog/spdlog.h>
int main()
{
spdlog::info("Hola spdlog");
return 0;
}
Con lo cual se obtiene:
[2021-04-15 18:20:28.157] [info] Hola spdlog
Fuentes
- Representaciones de fechas por países: Date and time representations
- Sobre el estándar ISO_8601
- Sobre milisegundos en C++
- Sobre chrono
- Sobre spdlog
Deja un comentario