你如何打印 C++11 时间点?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15777073/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:45:42  来源:igfitidea点击:

How do you print a C++11 time_point?

c++templatestimec++11chrono

提问by Trevor Hickey

I've created a time point, but I have been struggling to print it to the 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;
}

The only documentation I can find that prints a time_point is found here: http://en.cppreference.com/w/cpp/chrono/time_point

我能找到的唯一打印 time_point 的文档可以在这里找到:http://en.cppreference.com/w/cpp/chrono/time_point

however, I'm not even able to create a time_t based on my time_point(like the example).

但是,我什至无法根据我的 time_point(如示例)创建 time_t。

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

Error:

错误:

/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

采纳答案by HighCommander4

(In this post I will omit std::chrono::qualifications for clarity. I trust you know where they go.)

(在这篇文章中,std::chrono::为了清楚起见,我将省略限定条件。我相信你知道它们的去向。)

The reason your code example fails to compile is that there is a mismatch between the return type of system_clock::now()and the type of variable you are trying to assign this to (time_point<system_clock, nanoseconds>).

您的代码示例无法编译的原因是返回类型system_clock::now()与您尝试将其分配给 ( time_point<system_clock, nanoseconds>)的变量类型不匹配。

The documented return value of system_clock::now()is system_clock::time_point, which is a typedef for time_point<system_clock, system_clock::duration>. system_clock::durationis implementation-defined, with microsecondsand nanosecondsbeing commonly used. It seems that your implementation uses microseconds, so the return type of system_clock::now()is time_point<system_clock, microseconds>.

的记录返回值system_clock::now()is system_clock::time_point,它是time_point<system_clock, system_clock::duration>. system_clock::duration是实现定义的,与microsecondsnanoseconds被常用。似乎您的实现使用了microseconds,因此返回类型system_clock::now()time_point<system_clock, microseconds>

time_points with different durations are not implicitly convertible to one another, so you get a compiler error.

time_point具有不同持续时间的 s 不能相互隐式转换,因此您会收到编译器错误。

You can explicitlyconvert time points with different durations using time_point_cast, so the following would compile on your system:

您可以使用显式转换具有不同持续时间的时间点time_point_cast,因此以下内容将在您的系统上编译:

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

Notice the explicit template parameter to time_point_castis the target durationtype, not the target time_point type. The clock types must match in a time_point_cast, so specifying the entire time_point type (which is templated on both the clock type and the duration type) would be redundant.

注意显式模板参数 totime_point_cast是目标持续时间类型,而不是目标 time_point 类型。时钟类型必须在 a 中匹配time_point_cast,因此指定整个 time_point 类型(它是基于时钟类型和持续时间类型的模板)将是多余的。

Of course in your case, since you are just looking to print the time point, there is no need for it to be at any specific resolution, so you can just declare time_pointto be the same type as what system_clock::now()returns to begin with. A simple way to do that is to use the system_clock::time_pointtypedef:

当然,在您的情况下,由于您只是想打印时间点,因此不需要任何特定的分辨率,因此您可以声明time_pointsystem_clock::now()返回的类型相同。一个简单的方法是使用system_clock::time_pointtypedef:

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

Since this is C++11, you can also just use auto:

由于这是 C++11,您也可以使用auto

auto time_point = system_clock::now(); 

Having solved this compiler error, the conversion to time_tworks just fine:

解决了这个编译器错误后,转换time_t工作正常:

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

and you can now use standard methods for displaying time_tvalues, like std::ctimeor std::strftime. (As Cassio Neripoints out in a comment to your question, the more C++-y std::put_timefunction is not yet supported by GCC).

并且您现在可以使用标准方法来显示time_t值,例如std::ctimestd::strftime。(正如Cassio Neri在对您的问题的评论中指出的那样,std::put_timeGCC 尚不支持更多的 C++-y函数)。

回答by Matt Clarkson

This snippet might help you:

此代码段可能会帮助您:

#include <iomanip>
#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] = '
#include "date.h"
#include <iostream>

int
main()
{
    using namespace date;
    using namespace std::chrono;
    std::cout << system_clock::now() << " UTC\n";
}
'; // 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 }

回答by Howard Hinnant

Updated answer for an old question:

更新了一个旧问题的答案:

For a std::chrono::time_point<std::chrono::system_clock, some-duration>there is now a 3rd party libraries that give you much better control. For time_points based on other clocks, there is still no better solution than to just get the internal representation and print it out.

对于 astd::chrono::time_point<std::chrono::system_clock, some-duration>现在有一个 3rd 方库可以给你更好的控制。对于基于其他时钟的time_points,除了获取内部表示并打印出来之外,仍然没有更好的解决方案。

But for system_clock, using this library, this is as easy as:

但是对于system_clock,使用这个库,这很简单:

2016-07-19 03:21:01.910626 UTC

which just output for me:

这只是为我输出:

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

which is the current UTC date and time to microsecond precision. If on your platform system_clock::time_pointhas nanosecond precision, it will print out nanosecond precision for you.

这是当前 UTC 日期和时间到微秒精度。如果在您的平台上system_clock::time_point具有纳秒精度,它将为您打印出纳秒精度。

回答by Shafik Yaghmour

The nanosecondsseems to be part of the problem, looking at the documentation a bit I was able to get this to work:

nanoseconds似乎是问题的一部分,稍微看了一下文档,我能够让它工作:

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

Although it looks like std::chrono::microsecondsworks ok:

虽然看起来std::chrono::microseconds工作正常:

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

回答by user2394284

For anyone working with time_point<steady_clock>(not time_point<system_clock>):

对于与time_point<steady_clock>(不是time_point<system_clock>)一起工作的任何人:

//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;

The decimal number formatter is not the most efficient, but needs no beforehand knowledge of the number of decimals, which is not known if you want resolutionto be templated, unless you can come up with a constant expression for ceil(log10(resolution)).

十进制数字格式器不是最有效的,但不需要事先了解小数位数,如果您想resolution被模板化,这是不知道的,除非您可以为ceil(log10(resolution)).

回答by Longbow

The ctime() does not work for Visual C++. I use MS Visual Studio 2013. I changed the above code to use ctime_s(...), as prompted by MSVC compiler. It worked.

ctime() 不适用于 Visual C++。我使用 MS Visual Studio 2013。根据 MSVC 编译器的提示,我将上述代码更改为使用 ctime_s(...)。有效。

##代码##