74

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

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

7 回答 7

55

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

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

system_clock::now()is的记录返回值system_clock::time_point,它是time_point<system_clock, system_clock::duration>. system_clock::duration是实现定义的,有microseconds并且nanoseconds被普遍使用。看来你的实现使用microseconds了,所以返回类型system_clock::now()time_point<system_clock, microseconds>

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

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

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

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

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

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。(正如Cassio Neri在对您的问题的评论中指出的那样,std::put_timeGCC 尚不支持更多的 C++-y 函数)。

于 2013-04-03T02:52:38.310 回答
22

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

对于 astd::chrono::time_point<std::chrono::system_clock, some-duration>现在有一个 3rd 方库,可以让您更好地控制。对于基于其他时钟的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具有纳秒精度,它将为您打印出纳秒精度。

2021 更新

这是上述程序的 C++20 版本:

#include <chrono>
#include <iostream>

int
main()
{
    std::cout << std::chrono::system_clock::now() << " UTC\n";
}
于 2016-07-19T03:25:51.317 回答
18

此代码段可能会帮助您:

#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
}
于 2013-05-22T13:02:50.590 回答
12

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;
于 2013-04-03T01:07:34.320 回答
5

对于与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))

于 2017-07-03T12:54:35.717 回答
1

ctime() 不适用于 Visual C++。我使用 MS Visual Studio 2013。根据 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;
于 2016-05-06T15:56:43.237 回答
0

又是一段代码。优点是它相当独立并且支持微秒文本表示。

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();
}
于 2020-10-21T08:37:11.297 回答