web-dev-qa-db-fra.com

Comment imprimez-vous un time_point C ++ 11?

J'ai créé un point de temps, mais j'ai eu du mal à l'imprimer sur le terminal.

#include <iostream>
#include <chrono>

int main(){

    //set time_point to current time
    std::chrono::time_point<std::chrono::system_clock,std::chrono::nanoseconds> time_point;
    time_point = std::chrono::system_clock::now();

    //print the time
    //...

    return 0;
}

La seule documentation que je puisse trouver qui imprime un time_point se trouve ici: http://fr.cppreference.com/w/cpp/chrono/time_point

cependant, je ne suis même pas capable de créer un time_t basé sur mon time_point (comme dans l'exemple).

std::time_t now_c = std::chrono::system_clock::to_time_t(time_point); //does not compile

Erreur:

/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono: In instantiation of ‘constexpr std::chrono::time_point<_Clock, _Dur>::time_point(const std::chrono::time_point<_Clock, _Dur2>&) [with _Dur2 = std::chrono::duration<long int, std::ratio<1l, 1000000000l> >; _Clock = std::chrono::system_clock; _Dur = std::chrono::duration<long int, std::ratio<1l, 1000000l> >]’:
time.cpp:13:69:   required from here
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:540:32: error: no matching function for call to ‘std::chrono::duration<long int, std::ratio<1l, 1000000l> >::duration(std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<long int, std::ratio<1l, 1000000000l> > >::duration)’
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:540:32: note: candidates are:
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:247:14: note: template<class _Rep2, class _Period2, class> constexpr std::chrono::duration::duration(const std::chrono::duration<_Rep2, _Period2>&)
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:247:14: note:   template argument deduction/substitution failed:
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:243:46: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:240:23: note: template<class _Rep2, class> constexpr std::chrono::duration::duration(const _Rep2&)
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:240:23: note:   template argument deduction/substitution failed:
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:236:27: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:234:12: note: constexpr std::chrono::duration<_Rep, _Period>::duration(const std::chrono::duration<_Rep, _Period>&) [with _Rep = long int; _Period = std::ratio<1l, 1000000l>]
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:234:12: note:   no known conversion for argument 1 from ‘std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<long int, std::ratio<1l, 1000000000l> > >::duration {aka std::chrono::duration<long int, std::ratio<1l, 1000000000l> >}’ to ‘const std::chrono::duration<long int, std::ratio<1l, 1000000l> >&’
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:232:12: note: constexpr std::chrono::duration<_Rep, _Period>::duration() [with _Rep = long int; _Period = std::ratio<1l, 1000000l>]
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:232:12: note:   candidate expects 0 arguments, 1 provided
51
Trevor Hickey

(Dans ce post, je vais omettre les qualifications std::chrono:: Pour plus de clarté. Je pense que vous savez où elles vont.)

La compilation de votre exemple de code échoue parce que le type de retour system_clock::now(), retourné, et le type de variable que vous essayez d’affecter à celui-ci (time_point<system_clock, nanoseconds>).

La valeur de retour documentée de system_clock::now() est system_clock::time_point, Qui est un typedef pour time_point<system_clock, system_clock::duration>. system_clock::duration Est défini par l'implémentation, avec microseconds et nanoseconds couramment utilisés. Il semble que votre implémentation utilise microseconds, le type de retour de system_clock::now() est donc time_point<system_clock, microseconds>.

Les time_point De durées différentes ne sont pas convertibles implicitement les uns aux autres. Vous obtenez donc une erreur du compilateur.

Vous pouvez explicitement convertir des points de temps avec des durées différentes en utilisant time_point_cast. Ainsi, les éléments suivants seront compilés sur votre système:

time_point<system_clock, nanoseconds> time_point;
time_point = time_point_cast<nanoseconds>(system_clock::now());

Notez que le paramètre de modèle explicite à time_point_cast Est le type cible duration, et non le type de point de mesure time_point. Les types d'horloge doivent correspondre dans un time_point_cast, De sorte que spécifier le type de time_point entier (qui est basé sur le type d'horloge et le type de durée) serait redondant.

Bien sûr, dans votre cas, puisque vous cherchez seulement à imprimer le temps, il n’est pas nécessaire qu’il soit à une résolution spécifique, vous pouvez donc déclarer que time_point Est du même type que ce que system_clock::now() retourne pour commencer. Un moyen simple de le faire est d'utiliser le typedef system_clock::time_point:

system_clock::time_point time_point;
time_point = system_clock::now();  // no time_point_cast needed

Puisqu'il s'agit de C++ 11, vous pouvez aussi simplement utiliser auto:

auto time_point = system_clock::now(); 

Après avoir résolu cette erreur du compilateur, la conversion en time_t Fonctionne parfaitement:

std::time_t now_c = std::chrono::system_clock::to_time_t(time_point);

et vous pouvez maintenant utiliser des méthodes standard pour afficher les valeurs time_t, comme std::ctime ou std::strftime. (Comme Cassio Neri souligne dans un commentaire à votre question, plus la fonction C++ - y std::put_time N’est pas encore prise en charge par GCC).

50
HighCommander4

Cet extrait pourrait vous aider:

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

template<typename Clock, typename Duration>
std::ostream &operator<<(std::ostream &stream,
  const std::chrono::time_point<Clock, Duration> &time_point) {
  const time_t time = Clock::to_time_t(time_point);
#if __GNUC__ > 4 || \
    ((__GNUC__ == 4) && __GNUC_MINOR__ > 8 && __GNUC_REVISION__ > 1)
  // Maybe the put_time will be implemented later?
  struct tm tm;
  localtime_r(&time, &tm);
  return stream << std::put_time(&tm, "%c"); // Print standard date&time
#else
  char buffer[26];
  ctime_r(&time, buffer);
  buffer[24] = '\0';  // Removes the newline that is added
  return stream << buffer;
#endif
}

int main() {
  std::cout << std::chrono::system_clock::now() << std::endl;
  // Wed May 22 14:17:03 2013
}
15
Matt Clarkson

Réponse mise à jour pour une vieille question:

Pour un std::chrono::time_point<std::chrono::system_clock, some-duration> il existe maintenant une bibliothèque tierce qui vous donne un contrôle bien meilleur. Pour les points horaires basés sur d'autres horloges, il n'y a toujours pas de meilleure solution que de simplement obtenir la représentation interne et de l'imprimer.

Mais pour system_clock, en utilisant cette bibliothèque , c’est aussi simple que:

#include "date.h"
#include <iostream>

int
main()
{
    using namespace date;
    using namespace std::chrono;
    std::cout << system_clock::now() << " UTC\n";
}

qui vient de sortir pour moi:

2016-07-19 03:21:01.910626 UTC

qui est la date et l'heure UTC actuelles à la précision microseconde. Si sur votre plate-forme system_clock::time_point a une précision nanoseconde, il affichera une précision nanoseconde pour vous.

12
Howard Hinnant

Le nanoseconds semble faire partie du problème. En regardant un peu la documentation, j'ai pu le faire fonctionner:

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


int main(){

    //set time_point to current time
    std::chrono::time_point<std::chrono::system_clock> time_point;
    time_point = std::chrono::system_clock::now();

    std::time_t ttp = std::chrono::system_clock::to_time_t(time_point);
    std::cout << "time: " << std::ctime(&ttp);

    return 0;
}

Bien que cela ressemble à std::chrono::microseconds fonctionne bien:

std::chrono::time_point<std::chrono::system_clock,std::chrono::microseconds> time_point;
11
Shafik Yaghmour

Pour ceux qui travaillent avec time_point<steady_clock> (Pas time_point<system_clock>):

#include <chrono>
#include <iostream>

template<std::intmax_t resolution>
std::ostream &operator<<(
    std::ostream &stream,
    const std::chrono::duration<
        std::intmax_t,
        std::ratio<std::intmax_t(1), resolution>
    > &duration)
{
    const std::intmax_t ticks = duration.count();
    stream << (ticks / resolution) << '.';
    std::intmax_t div = resolution;
    std::intmax_t frac = ticks;
    for (;;) {
        frac %= div;
        if (frac == 0) break;
        div /= 10;
        stream << frac / div;
    }
    return stream;
}

template<typename Clock, typename Duration>
std::ostream &operator<<(
    std::ostream &stream,
    const std::chrono::time_point<Clock, Duration> &timepoint)
{
    typename Duration::duration ago = timepoint.time_since_Epoch();
    return stream << ago;
}

int main(){
    // print time_point
    std::chrono::time_point<std::chrono::steady_clock> now =
        std::chrono::steady_clock::now();
    std::cout << now << "\n";

    // print duration (such as the difference between 2 time_points)
    std::chrono::steady_clock::duration age = now - now;
    std::cout << age << "\n";
}

Le formateur de nombres décimaux n’est pas le plus efficace, mais ne nécessite aucune connaissance préalable du nombre de décimales, ce qui est impossible si vous souhaitez que resolution soit modélisé, à moins que vous ne puissiez obtenir une expression constante pour ceil(log10(resolution)).

2
user2394284

Le ctime () ne fonctionne pas pour Visual C++. J'utilise MS Visual Studio 2013. J'ai changé le code ci-dessus pour utiliser ctime_s (...), comme demandé par le compilateur MSVC. Ça a marché.

//set time_point to current time
std::chrono::time_point<std::chrono::system_clock> time_point;
time_point = std::chrono::system_clock::now();

std::time_t ttp = std::chrono::system_clock::to_time_t(time_point);
char chr[50];
errno_t e = ctime_s(chr, 50, &ttp);
if (e) std::cout << "Error." << std::endl;
else std::cout << chr << std::endl;
1
Longbow