web-dev-qa-db-fra.com

Comment convertir std :: chrono :: time_point en chaîne

Comment convertir std::chrono::time_point à la chaîne? Par exemple: "201601161125".

15
Seihyung Oh

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 strftimeici .

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.

7
srdjan.veljkovic

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
12
Howard Hinnant

Solution de code

La fonction suivante convertit de chronotime_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;

}

Fuseau horaire

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().

Sérialisation technique vs conviviale

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.

C++ 20

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
0
Adrian Maire