2017-03-02 20 views
2

どのようにロケールフリー変換std::chrono::time_pointに/ std::stringから事前に定義された日付時刻形式YYYY-mm-dd HH:MM:SS.zzzzzzzzzの?最後の二つは、 は高速STDから/へのstd ::クロノ:: time_point変換::文字列

    • 最初の二つは、std::tmtime_t(我慢)とCスタイルのインタフェースを持っている:

      For me it turned out唯一の方法は、std::itringstreamstd::ostringstreamstd::get_timestd::put_timeを使用することであるが、その遅いとstd::locale依存(重大)。

    他の代替手段はありますか?

    サードパーティのライブラリも考えられます。私はboost::posix_time::ptimeを見ましたが、継ぎ目もロケールに依存していて、それは遅いですし、std::chrono::time_pointより一般的ではありません。

  • +3

    これは基本的に「私にライブラリを探す」問題です。しかし...C++ 20標準化の提案があることが判明しました。 'chrono'標準ライブラリコンポーネントの後ろにあったHoward Hinnantが作ったものです。彼は(私たちのために)実装するのに十分なほど素晴らしかったです(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を簡単に書き込むことができます。たとえば、ここであなたはマイクロ秒の精度にsystem_clock::time_pointからintとしてフィールドタイプのすべてを得ることができる方法である。

    #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 Sをフォーマットすることができます。

    注1: gcc-6.1以前は、{}に関するコンパイラのバグがあります。代わりに()を使用して、コンパイラのバグを回避してください。 (int秒から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 Sを解析して、あなたは、単一のステートメントでsystem_clock::time_pointを形成することができます。

    ライブラリにはアクティブなユーザーコミュニティがあり、複数のプラットフォームでこのライブラリを維持できます。

    +0

    私は、C++の17のロケールに依存しない変換関数 'std :: from_chars'と' std :: to_chars'の 'std :: chrono :: time_point'のための一種のオーバーロードを探しています。ストリームはロケールに依存するので、 '' chrono_io.h ''は役に立ちません。 – Vahagn

    +0

    @Vahagn:最悪のシナリオ: 'time_point'から' y/m/dh:m:s'への変換(そしてその逆)のためだけにこのライブラリを使うことができ、I/Oはそれぞれのフィールドの積分値。このライブラリは、これらの非常に効率的な(反復不可能な)変換関数のタイプセーフなラッパーです:http://howardhinnant.github.io/date_algorithms.html –

    関連する問題