簡體   English   中英

你如何打印 C++11 time_point?

[英]How do you print a C++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_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

(在這篇文章中,為了清楚起見,我將省略std::chrono::限定條件。我相信你知道它們的去向。)

您的代碼示例無法編譯的原因是system_clock::now()的返回類型與您嘗試將其分配給 ( time_point<system_clock, nanoseconds> ) 的變量類型不匹配。

system_clock::now()的記錄返回值是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_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_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

由於這是 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在對您的問題的評論中指出的那樣,GCC 尚不支持更多的 C++-y std::put_time函數)。

更新了一個舊問題的答案:

對於std::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";
}

此代碼段可能會幫助您:

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

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;

對於使用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))提供一個常量表達式.

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;

又是一段代碼。 好的一面是它相當獨立並支持微秒文本表示。

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 如何打印原始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 s,第三方庫等。我一直在尋找一個最小的“按原樣打印此值”的解決方案,但沒有找到那么直接。 看來你不能簡單地打印一個::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();

相反,您似乎只能打印一個duration ,因此頂部所示的是一種創建持續時間的快速方法(來自此處),從now到紀元開始,這取決於您使用的時鍾(基本上, ::system_clock是掛鍾時間, ::steady_clock是一個單調時鍾,從某個點開始,比如系統開機)。 就我的目的而言, ::steady_clock無疑是更好的選擇,但只要我在比較蘋果與蘋果之間,就應該無關緊要。 我只是在尋找一些視覺反饋,而不是超級准確的東西。

我在這里創建了一個便簽本演示,演示如何打印我感興趣的時間點,以及::steady_clock::system_clock之間的一些差異。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM