[英]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
是實現定義的,通常使用microseconds
和nanoseconds
。 看來你實現使用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::ctime
或std::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
具有納秒精度,它將為您打印出納秒精度。
這是上述程序的 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();
}
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.