簡體   English   中英

怎么把std :: chrono :: time_point轉換成uint64_t?

[英]How to convert std::chrono::time_point to uint64_t?

我試圖通過查看數據的時間戳來查看我的數據是否舊120秒(或2分鍾),所以我在C ++中使用chrono包時具有以下代碼:

uint64_t now = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
// check for 2 minutes old data
bool is_old = (120 * 1000 < (now - data_holder->getTimestamp()));   

uint64_t value = now;
while (now < data_holder->getTimestamp() + 80 * 1000 
        && now < value + 80 * 1000) {
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    now = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
}

在上面的代碼中, data_holder->getTimestamp()是uint64_t,它以毫秒為單位返回時間戳。

現在,當我打印出來now變量的值,我看到這個10011360當我打印出來data_holder->getTimestamp()值是1437520382241

2015-07-21 16:13:02,530 WARN 0x7f35312d1700 data_check - now value: 10011360 , data holder timestamp: 1437520382241

從上面的數據持有者時間戳來看,它看起來不是120秒的舊數據,所以我覺得我的代碼有問題嗎? 因為如果我將數據持有人時間戳轉換為實際時間(使用紀元轉換器),然后將其與日志時間進行比較(如上所示),則幾乎是相同的。

因此,我決定使用system_clock而不是steady_clock並提出了以下代碼,其中我開始使用auto而不是uint64_t

解決方案A:

auto now = system_clock::now();
auto dh_ts = system_clock::time_point{milliseconds{data_holder->getTimestamp()}};
bool is_old = (minutes{2} < (now - dh_ts));

之前,我now使用變量值作為uint64_t而不是auto 現在在上面的代碼之后,我的原始代碼中有類似的內容,因為now不是uint64_t因此在編譯代碼時出現編譯錯誤。

uint64_t value = now;
while (now < data_holder->getTimestamp() + 80 * 1000 
        && now < value + 80 * 1000) {
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    now = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
}

解決此問題的正確方法是什么? 我不能更改data_holder->getTimestamp()數據類型,它必須是uint64_t因為其他代碼也在使用它。

這是錯誤:

error: cannot convert std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1l, 1000000000l> > >â to âuint64_t {aka long unsigned int}â in initialization

更新:

如果下面的一切看起來都不錯,我可以這樣使用而不是使用Solution A嗎?

解決方案B:

uint64_t now = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
bool is_old = (120 * 1000 < (now - data_holder->getTimestamp()));

至少在我讀到它時,它一次睡眠100毫秒,然后檢查它是否已經睡了2分鍾。 然后重復直到達到2分鍾為止。

在我看來,計算所需的時間並入睡直到那時更加有意義:

struct foo { 
    time_point<system_clock> time_stamp;

    time_point<system_clock> get_timestamp() { return time_stamp; }
    foo() : time_stamp(system_clock::now()) {}
};

// ...    
foo f;

std::this_thread::sleep_until(f.get_timestamp() + 2m);

這確實使用(C ++ 14中的新增功能)用戶定義的文字來構造2分鍾的持續時間。 如果確實需要支持較舊的(C ++ 11)編譯器,則需要改用minutes(2)

至於標題問題,我會說:只是說不。 將time_points存儲為實際time_points要比堅持將它們填充為整數,然后在需要再次使用它們時將它們變回time_points更好。 顯然,這並沒有完成任何有用的以換取痛苦的事情。

實際上,我建議您朝解決方案A的方向做更多的工作,並將uint64_t的其余時間轉換為time_points: chrono單位系統非常有用。 我將從定義一個輔助函數開始,以將對象上的uint64_t時間戳轉換為time_points:

using u64_millis = duration<uint64_t, milli>;
static time_point<system_clock, u64_millis> u64_to_time(uint64_t timestamp) {
    return time_point<system_clock, u64_millis>{u64_millis{timestamp}};
}

如果您的紀元與system_clock紀元不同,則可以在此處進行修復。 使用milliseconds代替u64_millis可能也可以工作,但是未明確定義milliseconds的表示形式,並且通過上述方式進行操作可確保類型正確匹配。

現在,您發布的代碼如下所示:

auto now = system_clock::now();
bool is_old = now - u64_to_time(data_holder->getTimestamp()) > minutes{2};

auto value = now;
while (now - u64_to_time(data_holder->getTimestamp()) < seconds{80}
        && now - value < seconds{80}) {
    this_thread::sleep_for(milliseconds{100});
    now = system_clock::now();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM