105 votes

Sortie de la date et de l'heure en C++ avec std::chrono

J'ai mis à jour un vieux code et j'ai essayé de passer à c++11 dans la mesure du possible. Le code suivant est la façon dont j'affichais 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 afficher l'heure et la date actuelles dans un format similaire en utilisant std::chrono(ou similaire) mais je ne sais pas comment m'y prendre. Toute aide serait grandement appréciée. Merci

137voto

bames53 Points 38303

En <chrono> ne traite que du temps et non des dates, à l'exception de l'option system_clock qui a la capacité de convertir ses points de temps en time_t . Ainsi, en utilisant <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 lointain.

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.

Mise à jour :

En utilisant une nouvelle version de Howard Hinnant. bibliothèque de dates 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 donnera quelque chose comme "2015-07-24 05:15:34.043473124 UTC".


Sur une note sans rapport, le retour const est devenu indésirable avec C++11 ; les valeurs de retour const ne peuvent pas être déplacées. J'ai également supprimé la terminaison const car la terminaison const n'est valable que pour les fonctions membres et cette fonction n'a pas besoin d'être membre.

59voto

Björn Sundin Points 124

Voici une solution C++20 :

#include <chrono>
#include <format>

std::string get_current_time_and_date()
{
    auto const time = std::chrono::current_zone()
        ->to_local(std::chrono::system_clock::now());
    return std::format("{:%Y-%m-%d %X}", time);
}

std::chrono::time_zone::to_local convertit un point de temps de l'horloge du système ( std::chrono::time_point<std::chrono::system_clock, TDuration> ) à un point temporel local ( std::chrono::local_time<TDuration> ). Ce point de temps local peut ensuite être formaté à l'aide de la fonction std::format avec des options de formatage similaires à strftime .

Actuellement, seul MSVC a implémenté std::format . Les ajouts de calendrier et de fuseau horaire au chrono
sont actuellement "partiellement" implémentés par Clang et GCC, mais vérifiez ici pour le statut mis à jour : https://en.cppreference.com/w/cpp/compiler_support . Pour plus d'informations sur le chrono bibliothèque, lisez ici : https://en.cppreference.com/w/cpp/chrono .

18voto

Jayhello Points 703

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

8voto

rodolk Points 510

Pour obtenir également 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/

7voto

Gang Liang Points 373

La bibliothèque fmt a la possibilité de formater tm structures : il a la même spécification que strftime.

#include <ctime>
#include <fmt/chrono.h>

std::string current_datetime(void)
{
  std::time_t tt = std::time(nullptr);
  std::tm *tm = std::localtime(&tt);
  return fmt::format("{:%Y%m%d}", *tm);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X