2013-04-03 81 views
34

我已經創建了一個時間點,但我一直在努力將其打印到終端。如何打印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 
+5

我相信'libstdC++'(也就是STL的GCC實現)不支持'std :: put_time',然後,cppreference中的示例不能編譯。請參閱http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html –

+0

順便說一下,如果您點擊「運行此代碼」,然後將編譯器更改爲「clang 3.4(C + +)」,cppreference上的示例將編譯。 +11)' – Cubbi

回答

36

(在這篇文章中,我將省略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 s不同持續時間不會隱式轉換爲另一個,因此您會收到編譯器錯誤。

您可以明確使用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值,L ike std::ctimestd::strftime。 (由於Cassio Neri在你的問題的評論中指出,GCC目前還不支持C++ - y std::put_time函數)。

+1

+1對於一個更徹底的解釋和提及'auto'(實際上,它是C++,沒有人聲明一個變量並將其分配到下一行,即使沒有'auto')。 –

+4

@HighCommander4:具有不同持續時間**的'time_point'是**可以隱式地相互轉換*如果它們共享相同的Clock並且如果rhs Duration可以隱式轉換爲lhs Duration。在這個例子中,如果'system_clock :: duration'是微秒或納秒,根據[time.point.cons]/p3它會*隱式轉換爲'time_point '。 –

8

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; 
+1

順便說一下,一個更簡潔的'auto time_point = std :: chrono :: system_clock :: now();'也可能完成。 –

+1

@ChristianRau當然,公平點,我通常喜歡儘可能地保持代碼儘可能接近原始發佈的代碼,除非它明顯地被破壞或錯誤。 –

10

這個片段可以幫助你:

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

只有'std :: chrono :: system_clock'支持'to_time_t',所以我認爲將它作爲模板是沒有意義的。相反,time_point可以直接作爲'const system_clock :: time_point&time_point'傳遞。 –

+1

取決於用戶是否創建了具有'to_time_t'的用戶定義時鐘。 –

+0

你也應該'#include '。 – thiagowfx

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." << endl; 
else std::cout << chr << std::endl; 
6

的一個老問題更新答案:

對於std::chrono::time_point<std::chrono::system_clock, some-duration>現在有,讓你更好地控制第三方庫。對於基於其他時鐘的時間點,仍然沒有比只獲得內部表示並將其打印出來更好的解決方案。

但對於system_clock,使用this library,這是那麼容易,因爲:

#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具有納秒精度,則會爲您打印出納秒精度。

+4

嗯,這應該是在標準艾莫。 –

+3

@AbhinavGauniyal:在此工作(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0355r1.html)。這很可能需要**你的**非常聲樂的幫助。委員會中的重要力量不喜歡這個提議,如果公衆沒有把他們喊出來,他們將贏得勝利。 –

+0

可以對抗什麼樣的論點??? – akim

1

對於任何與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) 
{ 
    typename Duration::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))的常量表達式。