8

として表される小数のエポック タイムスタンプがあり、doubleこれを適切な に変換したいと考えていますstd::chrono::time_point。エポックは、1970 年 1 月 1 日以降の通常の UNIX エポックです。が存在することは知っていますがstd::chrono::system_clock::from_time_t、a にtime_tは小数部分がありません。C++11 でこれを行う最善の方法は何でしょうか?

この質問は、Boost::posix_time::ptimeへの unix タイムスタンプに関連していますが、Boost バージョンではなく C++11 を要求していることを除きます。

4

1 に答える 1

13

clockエポックが既知のタイプと同じであると仮定すると、double表現で期間を使用し、そのクロックで使用される期間に変換できます。

// change period to appropriate units - I'm assuming seconds
typedef std::chrono::duration<double, std::ratio<1>> d_seconds;

d_seconds since_epoch_full(324324.342);
auto since_epoch = std::chrono::duration_cast<clock::duration>(since_epoch_full);
clock::time_point point(since_epoch);

クロックと同じ精度を使用しているため、そのクロックを含む計算ではこれで問題ありませんが、変換で精度が失われる可能性があります。それを失いたくない場合は、そのベースの期間タイプを使用するtime_point特殊化を使用する必要があります。doubleそして、それを計算に使用します (もちろん、浮動小数点演算のすべての注意事項があります)。

typedef std::chrono::time_point<clock, d_seconds> d_time_point;

ただし、変換が必要になるため、同じクロックを含む計算が複雑になります。これを簡単にするために、変換を行い、それを使用する独自のクロック ラッパーを作成できます。

template <typename Clock>
struct my_clock_with_doubles {
    typedef double rep;
    typedef std::ratio<1> period;
    typedef std::chrono::duration<rep, period> duration;
    typedef std::chrono::time_point<my_clock_with_doubles<Clock>> time_point;
    static const bool is_steady = Clock::is_steady;

    static time_point now() noexcept {
        return time_point(std::chrono::duration_cast<duration>(
                   Clock::now().time_since_epoch()
               ));
    }

    static time_t to_time_t(const time_point& t) noexcept {
        return Clock::to_time_t(typename Clock::time_point(
                             std::chrono::duration_cast<typename Clock::duration>(
                                 t.time_since_epoch()
                             )
                        ));
    }
    static time_point from_time_t(time_t t) noexcept {
        return time_point(std::chrono::duration_cast<duration>(
                   Clock::from_time_t(t).time_since_epoch()
               ));
    }
};
于 2012-02-10T00:31:47.873 に答える