Как вы печатаете С++ 11 time_point?

Я создал точку времени, но я изо всех сил пытался распечатать ее на терминале.

#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;
}

Единственная документация, которую я могу найти, которая печатает точку time_point, находится здесь: http://en.cppreference.com/w/cpp/chrono/time_point

однако, я даже не могу создать time_t на основе моей time_point (например, пример).

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

Ошибка:

/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

Ответ 1

(В этом посте я буду опускать квалификацию std::chrono:: для ясности. Надеюсь, вы знаете, куда они идут.)

Причина, по которой ваш пример кода не скомпилирован, заключается в несоответствии между типом возвращаемого значения system_clock::now() и типом переменной, которую вы пытаетесь назначить (time_point<system_clock, nanoseconds>).

Документированное возвращаемое значение system_clock::now() равно system_clock::time_point, которое является typedef для time_point<system_clock, system_clock::duration>. system_clock::duration определяется реализацией, обычно используется microseconds и nanoseconds. Кажется, что в вашей реализации используется microseconds, поэтому возвращаемый тип system_clock::now() равен time_point<system_clock, microseconds>.

time_point с разными длительностями неявно конвертируются друг в друга, поэтому вы получаете ошибку компилятора.

Вы можете явно преобразовать точки времени с разными длительностями с помощью time_point_cast, поэтому в вашей системе будет компилироваться следующее:

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

Обратите внимание, что параметр явного шаблона time_point_cast - это целевой тип продолжительность, а не тип target_time_point. Типы часов должны совпадать в time_point_cast, поэтому указание всего типа time_point (который является шаблоном как для типа часов, так и для типа продолжительности) будет избыточным.

Конечно, в вашем случае, поскольку вы просто хотите распечатать временной момент, нет необходимости в том, чтобы он был в каком-либо конкретном разрешении, поэтому вы можете просто объявить time_point тем же типом, что и system_clock::now() начинается с начала. Простой способ сделать это - использовать system_clock::time_point typedef:

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

Так как это С++ 11, вы также можете просто использовать auto:

auto time_point = system_clock::now(); 

Решив эту ошибку компилятора, преобразование в time_t работает просто отлично:

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

и теперь вы можете использовать стандартные методы для отображения значений time_t, таких как std::ctime или std::strftime. (Как Cassio Neri указывает в комментарии к вашему вопросу, тем больше функция С++ - y std::put_time еще не поддерживается GCC).

Ответ 2

Этот фрагмент может помочь вам:

#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
}

Ответ 3

nanoseconds, кажется, является частью проблемы, немного посмотрев на документацию, я смог заставить это работать:

#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;
}

Хотя это выглядит как std::chrono::microseconds работает нормально:

std::chrono::time_point<std::chrono::system_clock,std::chrono::microseconds> time_point;

Ответ 4

Обновленный ответ для старого вопроса:

При a std::chrono::time_point<std::chrono::system_clock, some-duration> теперь есть сторонние библиотеки, которые дают вам гораздо лучший контроль. Для time_points, основанных на других часах, все еще нет лучшего решения, чем просто получить внутреннее представление и распечатать его.

Но для system_clock, используя эту библиотеку, это так же просто, как:

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

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

который просто выводит для меня:

2016-07-19 03:21:01.910626 UTC

которая является текущей датой и временем UTC до микросекундной точности. Если на вашей платформе system_clock::time_point будет наносекундная точность, она будет печатать для вас наносекундную точность.

Ответ 5

ctime() не работает для Visual С++. Я использую MS Visual Studio 2013. Я изменил приведенный выше код, чтобы использовать ctime_s (...), как было предложено компилятором MSVC. Это сработало.

//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." << endl;
else std::cout << chr << std::endl;

Ответ 6

Для тех, кто работает с time_point<steady_clock> (not 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";
}

Форматирование десятичных чисел не является наиболее эффективным, но не требует предварительного знания количества десятичных знаков, что неизвестно, хотите ли вы, чтобы resolution был шаблоном, если вы не можете найти постоянное выражение для ceil(log10(resolution)).