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

我已经创建了一个时间点,但我一直在努力打印到终端。

#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 _ point 创建 time _ t (如示例所示)。

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
99172 次浏览

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;

(在这篇文章中,为了清楚起见,我将省略 std::chrono::的资格要求。我相信你知道它们的用途。)

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

记录的 system_clock::now()返回值是 system_clock::time_point,它是 time_point<system_clock, system_clock::duration>的 typedef。system_clock::duration是实现定义的,通常使用 microsecondsnanoseconds。似乎您的实现使用 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的显式模板参数是目标 持续时间类型,而不是目标 time _ point 类型。时钟类型必须在 time_point_cast中匹配,因此指定整个 time _ point 类型(在时钟类型和持续时间类型上都有模板)将是多余的。

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

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

因为这是 C + + 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::ctimestd::strftime。(正如 凯西奥 · 内里在对您的问题的评论中指出的那样,GCC 还不支持更多的 C + +-y std::put_time函数)。

这个片段可能会对你有所帮助:

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

Ctime ()不适用于 Visual C + + 。我使用的是 MSVisualStudio2013。根据 MSVC 编译器的提示,我将上面的代码更改为使用 ctime _ s (...)。成功了。

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

一个老问题的最新答案:

对于一个 std::chrono::time_point<std::chrono::system_clock, some-duration>,现在有一个第三方库,可以让您更好地控制。对于基于其他时钟的 time _ point,仍然没有比仅仅获取内部表示并将其打印出来更好的解决方案。

但是对于使用 这个图书馆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有纳秒级的精度,它会为你打印出纳秒级的精度。

2021年最新情况

下面是上面程序的 C + + 20版本:

#include <chrono>
#include <iostream>


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

对于任何使用 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";
}

十进制数格式化程序并不是最有效的,但是它不需要事先知道小数的数量,如果您想要模板化 resolution,则不知道这一点,除非您能够为 ceil(log10(resolution))提供一个常量表达式。

还有一段代码。 另一方面,它是相当独立的,并支持微秒文本表示。

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();
}

如何打印原始 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;
}

天哪,我原以为只需要30秒的谷歌搜索就能变成一个深入兔子洞的研究项目。我只想在程序中打印出一些原始的时间点,以便在视觉上对它们进行比较,对漂亮的打印不感兴趣。我相信这些其他的答案也可以,但是他们有很多代码,使用 ctime struct,第三方库等等。我正在寻找一个最小化的,“按原样打印此值”的解决方案,但没有找到太多直接的解决方案。似乎你不能简单地打印一个 ::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();

相反,你似乎只能打印一个 持续时间,所以上面的说明是一个快速创建一个持续时间的方法(来源于 给你) ,从 now到新纪元的开始,这取决于你使用的时钟不同(基本上,::system_clock是墙上的时钟,而 ::steady_clock是一个单调的时钟,从某一点开始,如系统电源)。就我的目的而言,::steady_clock无疑是更好的选择,但只要我把苹果和苹果进行比较,它就不应该那么重要。我只是在寻找一些视觉反馈,而不是一些超级准确的东西。

我在这里创建了一个暂存版 示范,它介绍了如何打印我感兴趣的时间点,以及 ::steady_clock::system_clock之间的一些差异。