2017-03-02 267 views
2

如何區域無轉換std::chrono::time_point向/從預定日期時間格式YYYY-mm-dd HH:MM:SS.zzzzzzzzzstd::stringtime_point快速轉換的std ::時辰:: /從的std :: string

For me it turned out,唯一的辦法就是使用std::get_timestd::put_timestd::itringstreamstd::ostringstream,但:

  • 前兩個有std::tmtime_t(忍受)
  • 最後兩個是C風格的界面(關鍵)緩慢和std::locale

還有其他的選擇嗎?

第三方庫也可以考慮。我看着boost::posix_time::ptime,但接縫也是由區域決定的,加上它比std::chrono::time_point更慢,通用性也更低。

+3

這基本上是一個「找我一個圖書館」的問題。但...事實證明,有一個提議用於C++ 20標準化。由Howard Hinnant製作,後者是'chrono'標準庫組件的後臺。他甚至足夠[爲我們實現它](https://github.com/HowardHinnant/date);)。 –

+0

@NicolBolas,爲什麼不把它變成答案? –

+0

@D_N:因爲這是一個應該關閉的問題。 –

回答

2

不知道這是否是對你不夠快,但:

#include "date.h" 
#include <iostream> 

int 
main() 
{ 
    using namespace date; 
    std::cout << std::chrono::system_clock::now() << '\n'; 
} 

只輸出對我來說:

2017-03-02 17:04:26.813110 

這是我寫的庫。它是免費的,開放源代碼,並且"date.h"部分僅爲標頭。有full documentation,甚至視頻教程,所有鏈接的GitHub page

有相當豐富的格式和解析選項,以及許多其他功能,使它安全和容易做時間和日曆計算。

此外,如果此格式對您而言速度不夠快,則該庫可靈活分層,以便您可以在較低級別與其交互,並輕鬆編寫自己的I/O。例如這裏是你如何能得到字段類型所有intsystem_clock::time_point到微秒精度:

#include "date.h" 

int 
main() 
{ 
    using namespace date; 
    using namespace std::chrono; 
    auto t = system_clock::now(); 

    // Convert system_clock::time_point to days-precision time_point 
    auto sd = floor<days>(t); 
    // Create time_of_day 
    auto tod = make_time(t - sd); 
    // Create year_month_day 
    year_month_day ymd = sd; 

    // Extract field types as int 
    int y = int{ymd.year()}; // Note 1 
    int m = unsigned{ymd.month()}; 
    int d = unsigned{ymd.day()}; 
    int h = tod.hours().count(); 
    int M = tod.minutes().count(); 
    int s = tod.seconds().count(); 
    int us = duration_cast<microseconds>(tod.subseconds()).count(); 
} 

現在,您可以格式化這些int小號不過你想要的。

注1:在gcc-6.1之前,在這裏有一個關於{}的編譯器錯誤。改用()來解決編譯器錯誤。

走向相反的方向(從int s到system_clock::time_point)更容易:

#include "date.h" 

int 
main() 
{ 
    using namespace date; 
    using namespace std::chrono; 
    int y = 2017; 
    int m = 3; 
    int d = 2; 
    int h = 15; 
    int M = 33; 
    int s = 55; 
    int us = 123456; 

    // Convert field values to system_clock::time_point 
    system_clock::time_point t = sys_days(year{y}/m/d) + hours{h} + minutes{M} + 
           seconds{s} + microseconds{us}; 
} 

解析您的int小號,但是你想,然後就可以形成一個單一的語句system_clock::time_point

該圖書館有一個活躍的用戶社區,有助於在多個平臺上進行維護。

+0

我正在尋找一種重載的'std :: chrono :: time_point'的C++ 17提出的區域獨立轉換函數'std :: from_chars'和'std :: to_chars'。這些流是依賴locale的,所以''chrono_io.h''不會幫助。 – Vahagn

+0

@Vahagn:最糟糕的情況:您可以使用這個庫僅用於'time_point'到'y/m/dh:m:s'的轉換(反之亦然),I/O是每個這些字段的整數值。這個庫是這些非常高效(非迭代)轉換函數的類型安全包裝:http://howardhinnant.github.io/date_algorithms.html –