Comment convertir std::chrono::time_point
à la chaîne? Par exemple: "201601161125"
.
Le moyen le plus flexible de le faire est de le convertir en struct tm
puis utilisez strftime
(c'est comme sprintf
pour le temps). Quelque chose comme:
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::time_t now_c = std::chrono::system_clock::to_time_t(now);
std::tm now_tm = *std::localtime(&now_c);
/// now you can format the string as you like with `strftime`
Recherchez la documentation de strftime
ici .
Si tu as localtime_s
ou localtime_r
disponible, vous devez utiliser soit de préférence à localtime
.
Il existe de nombreuses autres façons de le faire, mais, bien que plus faciles à utiliser, elles entraînent une représentation de chaîne prédéfinie. Vous pouvez simplement "masquer" tout ce qui précède dans une fonction pour en faciliter l'utilisation.
la bibliothèque de date/heure portable, libre, open source, en-tête uniquement, Howard Hinnant est une façon moderne de faire cela qui ne fait pas de trafic via l'ancienne API C, et ne nécessite pas que vous jetiez tout de vos informations en moins d'une seconde. Cette bibliothèque est également proposée pour la normalisation .
Il y a beaucoup de flexibilité dans le formatage. Le moyen le plus simple consiste à simplement diffuser:
#include "date.h"
#include <iostream>
int
main()
{
using namespace date;
std::cout << std::chrono::system_clock::now() << '\n';
}
Cela vient de sortir pour moi:
2017-09-15 13:11:34.356648
Le using namespace date;
est requis pour trouver l'opérateur de streaming pour le system_clock::time_point
(il n'est pas légal pour ma bibliothèque de l'insérer dans namespace std::chrono
). Aucune information n'est perdue dans ce format: la pleine précision de votre system_clock::time_point
sera affiché (microseconds
où je l'ai exécuté sur macOS).
La suite complète de strftime
- drapeaux de formatage de type _ est disponible pour d'autres formats, avec des extensions mineures pour gérer des choses comme les secondes fractionnaires. Voici un autre exemple qui sort avec une précision en millisecondes:
#include "date.h"
#include <iostream>
int
main()
{
using namespace date;
using namespace std::chrono;
std::cout << format("%D %T %Z\n", floor<milliseconds>(system_clock::now()));
}
qui vient de sortir pour moi:
09/15/17 13:17:40.466 UTC
La fonction suivante convertit de chrono
time_point
En chaîne (sérialisation).
#include <chrono>
#include <iomanip>
#include <sstream>
using time_point = std::chrono::system_clock::time_point;
std::string serializeTimePoint( const time_point& time, const std::string& format)
{
std::time_t tt = std::chrono::system_clock::to_time_t(time);
std::tm tm = *std::gmtime(&tt); //GMT (UTC)
//std::tm tm = *std::localtime(&tt); //Locale time-zone, usually UTC by default.
std::stringstream ss;
ss << std::put_time( &tm, format.c_str() );
return ss.str();
}
// example
int main()
{
time_point input = std::chrono::system_clock::now();
std::cout << serializeTimePoint(input, "UTC: %Y-%m-%d %H:%M:%S") << std::endl;
}
Le type de données time_point
N'a pas de représentation interne pour le fuseau horaire, par conséquent, le fuseau horaire est agrégé par la conversion en std::tm
(Par les fonctions gmtime
ou localtime
). Il n'est pas recommandé d'ajouter/de soustraire le fuseau horaire de l'entrée, car vous obtiendrez un fuseau horaire incorrect affiché avec %Z
, Il est donc préférable de définir l'heure locale correcte (en fonction du système d'exploitation) et utilisez localtime()
.
Pour un usage technique, le format horaire codé en dur est une bonne solution. Cependant, pour afficher aux utilisateurs, il faut utiliser un locale
pour récupérer la préférence de l'utilisateur et afficher l'horodatage dans ce format.
Depuis C++ 20, nous avons de jolies fonctions de sérialisation et d'analyse pour time_point et duration.
std::chrono::to_stream
std::chrono::format