简体   繁体   English

你如何打印 C++11 time_point?

[英]How do you print a C++11 time_point?

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

(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::now()的记录返回值是system_clock::time_point ,它是time_point<system_clock, system_clock::duration> system_clock::duration is implementation-defined, with microseconds and nanoseconds being commonly used. system_clock::duration是实现定义的,通常使用microsecondsnanoseconds It seems that your implementation uses microseconds , so the return type of system_clock::now() is time_point<system_clock, microseconds> .看来你实现使用microseconds ,这样的返回类型system_clock::now()time_point<system_clock, microseconds>

time_point s with different durations are not implicitly convertible to one another, so you get a compiler error.具有不同持续时间的time_point不能相互隐式转换,因此您会收到编译器错误。

You can explicitly convert 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_cast is the target duration type, not the target time_point type.注意time_point_cast的显式模板参数是目标持续时间类型,而不是目标 time_point 类型。 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.时钟类型必须在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_point to be the same type as what system_clock::now() returns to begin with.当然,在您的情况下,由于您只是想打印时间点,因此不需要它具有任何特定分辨率,因此您可以将time_point声明为与system_clock::now()返回的类型相同开始。 A simple way to do that is to use the system_clock::time_point typedef:一个简单的方法是使用system_clock::time_point typedef:

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_t works 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_t values, like std::ctime or std::strftime .并且您现在可以使用标准方法来显示time_t值,例如std::ctimestd::strftime (As Cassio Neri points out in a comment to your question, the more C++-y std::put_time function is not yet supported by GCC). (正如Cassio Neri在对您的问题的评论中指出的那样,GCC 尚不支持更多的 C++-y std::put_time函数)。

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.对于std::chrono::time_point<std::chrono::system_clock, some-duration>现在有一个 3rd 方库可以给你更好的控制。 For time_points based on other clocks, there is still no better solution than to just get the internal representation and print it out.对于基于其他时钟的time_points,除了获取内部表示并打印出来之外,仍然没有更好的解决方案。

But for system_clock , using this library , this is as easy as:但是对于system_clock ,使用这个库,这很简单:

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

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

which just output for me:这只是为我输出:

2016-07-19 03:21:01.910626 UTC

which is the current UTC date and time to microsecond precision.这是当前 UTC 日期和时间到微秒精度。 If on your platform system_clock::time_point has nanosecond precision, it will print out nanosecond precision for you.如果在您的平台上system_clock::time_point具有纳秒精度,它将为您打印出纳秒精度。

2021 Update 2021 更新

Here is the C++20 version of the above program:这是上述程序的 C++20 版本:

#include <chrono>
#include <iostream>

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

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] = '\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
}

The nanoseconds seems to be part of the problem, looking at the documentation a bit I was able to get this to work: 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;
}

Although it looks like std::chrono::microseconds works ok:虽然它看起来像std::chrono::microseconds工作正常:

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

For anyone working with time_point<steady_clock> (not time_point<system_clock> ):对于使用time_point<steady_clock> (不是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)
{
    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";
}

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 resolution to be templated, unless you can come up with a constant expression for ceil(log10(resolution)) .十进制数字格式器不是最有效的,但不需要事先了解小数位数,如果您想对resolution进行模板化,则不知道这一点,除非您可以为ceil(log10(resolution))提供一个常量表达式.

The ctime() does not work for Visual C++. ctime() 不适用于 Visual C++。 I use MS Visual Studio 2013. I changed the above code to use ctime_s(...), as prompted by MSVC compiler.我使用 MS Visual Studio 2013。根据 MSVC 编译器的提示,我将上述代码更改为使用 ctime_s(...)。 It worked.有效。

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

Yet another snippet of code.又是一段代码。 Plus side is that it is fairly standalone and supports microsecond text representation.好的一面是它相当独立并支持微秒文本表示。

std::ostream& operator<<(std::ostream& stream, const std::chrono::system_clock::time_point& point)
{
    auto time = std::chrono::system_clock::to_time_t(point);
    std::tm* tm = std::localtime(&time);
    char buffer[26];
    std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S.", tm);
    stream << buffer;
    auto duration = point.time_since_epoch();
    auto seconds = std::chrono::duration_cast<std::chrono::seconds>(duration);
    auto remaining = std::chrono::duration_cast<std::chrono::nanoseconds>(duration - seconds);
    // remove microsecond cast line if you would like a higher resolution sub second time representation, then just stream remaining.count()
    auto micro = std::chrono::duration_cast<std::chrono::microseconds>(remaining);
    return stream << micro.count();
}

tl;dr How to print a raw std::chrono::time_point tl;dr 如何打印原始std::chrono::time_point

#include <iostream>
#include <chrono>

int main()
{
  // begin is a std::chrono::time_point type
  // You can also use ::system_clock::now() to get the time since
  // Jan 1 1970 (differences between these linked below)
  auto begin = std::chrono::steady_clock::now();

  // print as nanoseconds. Can also choose ::microseconds, ::seconds, ::minutes,
  // ::hours. The type returned from .time_since_epoch() is
  // std::chrono::duration
  std::cout << "begin: " << std::chrono::duration_cast<std::chrono::nanoseconds>(begin.time_since_epoch()).count();

  return 0;
}

Goodness, what I thought would be a 30 second google search turned into a research project down the rabbit hole.天哪,我原以为 30 秒的谷歌搜索变成了一个陷入困境的研究项目。 All I wanted to do print out some raw time points in my program to compare them visually, no interest in pretty print.我只想在我的程序中打印出一些原始时间点,以便在视觉上比较它们,对漂亮的打印不感兴趣。 I'm sure these other answers work too, but they have a whole lot of code, use ctime struct s, 3rd party libraries, etc. I was looking for a minimal, "print this value as is" solution, and didn't find much that direct.我确信这些其他答案也有效,但它们有很多代码,使用 ctime struct s,第三方库等。我一直在寻找一个最小的“按原样打印此值”的解决方案,但没有找到那么直接。 It seems that you can't simply print a ::time_point :看来你不能简单地打印一个::time_point

auto begin = std::chrono::steady_clock::now();
// BAD CODE, none of these work, in C++17 anyway
std::cout << begin;
std::cout << std::chrono::time_point_cast<std::chrono::nanoseconds>(begin);
std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(begin).count();
std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(begin - 0).count();

Rather, it appears you can only print a duration , so what's illustrated at the top is a quick way of creating a duration (sourced from here ), from now until the beginning of the epoch, which differs depending on the clock you use (basically, the ::system_clock is the wall clock time, and the ::steady_clock is a monotonic clock that begins at some point, such as system power on).相反,您似乎只能打印一个duration ,因此顶部所示的是一种创建持续时间的快速方法(来自此处),从now到纪元开始,这取决于您使用的时钟(基本上, ::system_clock是挂钟时间, ::steady_clock是一个单调时钟,从某个点开始,比如系统开机)。 For my purposes, the ::steady_clock is surely the better choice, but shouldn't matter all that much as long as I'm comparing apples to apples.就我的目的而言, ::steady_clock无疑是更好的选择,但只要我在比较苹果与苹果之间,就应该无关紧要。 I was just looking for some visual feedback, not something super accurate.我只是在寻找一些视觉反馈,而不是超级准确的东西。

I've created a scratchpad demonstration here of how to print the time points I was interested in, and some differences between ::steady_clock and ::system_clock .我在这里创建了一个便签本演示,演示如何打印我感兴趣的时间点,以及::steady_clock::system_clock之间的一些差异。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM