web-dev-qa-db-fra.com

Afficher la date et l'heure en C++ à l'aide de std :: chrono

J'ai mis à jour un ancien code et j'ai essayé de mettre à jour vers c ++ 11 dans la mesure du possible. Le code suivant montre comment j'avais l'habitude d'afficher l'heure et la date dans mon programme

#include <iostream>
#include <string>
#include <stdio.h>
#include <time.h>

const std::string return_current_time_and_date() const
{
    time_t now = time(0);
    struct tm tstruct;
    char buf[80];
    tstruct = *localtime(&now);
    strftime(buf, sizeof(buf), "%Y-%m-%d %X", &tstruct);
    return buf;
}

Je voudrais sortir l'heure et la date actuelles dans un format similaire en utilisant std :: chrono (ou similaire) mais je ne sais pas comment s'y prendre. Toute aide serait grandement appréciée. Merci

49
const_ref

La bibliothèque <chrono> traite uniquement de l'heure et non des dates, à l'exception du system_clock qui a la capacité de convertir ses points horaires en time_t. Donc, utiliser <chrono> pour les dates n'améliorera pas beaucoup les choses. Espérons que nous obtiendrons quelque chose comme chrono::date dans un avenir pas trop éloigné.

Cela dit, vous pouvez utiliser <chrono> de la manière suivante:

#include <chrono>  // chrono::system_clock
#include <ctime>   // localtime
#include <sstream> // stringstream
#include <iomanip> // put_time
#include <string>  // string

std::string return_current_time_and_date()
{
    auto now = std::chrono::system_clock::now();
    auto in_time_t = std::chrono::system_clock::to_time_t(now);

    std::stringstream ss;
    ss << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d %X");
    return ss.str();
}

Notez que std::localtime peut provoquer des courses de données. localtime_r ou des fonctions similaires peuvent être disponibles sur vos plateformes.

Mettre à jour:

En utilisant une nouvelle version de date library - de Howard Hinnant vous pouvez écrire:

#include "date.h"
#include <chrono>
#include <string>
#include <sstream>

std::string return_current_time_and_date() {
  auto now = std::chrono::system_clock::now();
  auto today = date::floor<days>(now);

  std::stringstream ss;
  ss << today << ' ' << date::make_time(now - today) << " UTC";
  return ss.str();
}

Cela affichera quelque chose comme "2015-07-24 05: 15: 34.043473124 UTC".


Sur une note indépendante, renvoyer des objets const est devenu indésirable avec C++ 11; Les valeurs de retour const ne peuvent pas être déplacées. J'ai également supprimé le const de fin, car le const de fin n'est valide que pour les fonctions membres et cette fonction n'a pas besoin d'être membre.

76
bames53

Un exemple:

#include <iostream>
#include <chrono>
#include <ctime>

std::string getTimeStr(){
    std::time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());

    std::string s(30, '\0');
    std::strftime(&s[0], s.size(), "%Y-%m-%d %H:%M:%S", std::localtime(&now));
    return s;
}
int main(){

    std::cout<<getTimeStr()<<std::endl;
    return 0;

}

Sortie comme ci-dessous:

 enter image description here

3
Jayhello

les solutions de bames53 sont bonnes, mais ne compilez pas sur mon VS2017. La solution avec ctime ne compile pas car localtime est très obsolète. Celui avec date.h ne compile pas avec la date actuelle.h Je viens de retirer github, même si la documentation le dit, car cela ne devrait pas être le cas, car la journée ne peut pas être diffusée telle quelle. J'ai omis l'inclus mais voici le code qui fonctionne:

void TimeTest()
{
    auto n = std::chrono::system_clock::now();
    auto in_time_t = std::chrono::system_clock::to_time_t(n);
    std::tm buf;
    localtime_s(&buf, &in_time_t);
    std::cout << std::put_time(&buf, "%Y-%m-%d %X") << std::endl;

}

// I just added date.h from this link's guthub to the project.
// https://howardhinnant.github.io/date/date.html
void TimeTest1() {
    auto now = std::chrono::system_clock::now();
    auto today =  floor<date::days>(std::chrono::system_clock::now());
    std::cout << date::year_month_day{ today } << ' ' << date::make_time(now - today) << std::endl;
}

// output is 
// 2018-04-08 21:19:49
// 2018-04-08 18:19:49.8408289

N'hésitez pas à réparer la solution bames53 et à supprimer la mienne. Mon texte ne rentre tout simplement pas dans un commentaire. Je suis sûr que cela peut sauver beaucoup de gens du chagrin.

2
Yaniv

Vous pouvez améliorer la réponse de @ bames53 en utilisant Boost lexical_cast au lieu des manipulations de flux de chaînes.

Voici ce que je fais:

#include <boost/lexical_cast.hpp>
#include <ctime>

std::string return_current_time_and_date() {
    auto current_time = std::time(0);
    return boost::lexical_cast<std::string>(std::put_time(std::gmtime(& current_time), "%Y-%m-%d %X"));
}
0
Xavier Lamorlette

Pour obtenir aussi des millisecondes, j'utilise chrono et la fonction C localtime_r qui est thread-safe (contrairement à std :: localtime).

#include <iostream>
#include <chrono>
#include <ctime>
#include <time.h>
#include <iomanip>


int main() {
  std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
  std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
  std::chrono::milliseconds now2 = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_Epoch());
  struct tm currentLocalTime;
  localtime_r(&currentTime, &currentLocalTime);
  char timeBuffer[80];
  std::size_t charCount { std::strftime( timeBuffer, 80,
                                         "%D %T",
                                          &currentLocalTime)
                         };

  if (charCount == 0) return -1;

  std::cout << timeBuffer << "." << std::setfill('0') << std::setw(3) << now2.count() % 1000 << std::endl;
  return 0;
}

Pour le format: http://www.cplusplus.com/reference/ctime/strftime/

0
rodolk