簡體   English   中英

C ++將字符串時間戳轉換為std :: chrono :: system_clock :: time_point

[英]C++ Convert a string timestamp to std::chrono::system_clock::time_point

我試圖通過保留微秒精度將以以下格式表示的字符串時間戳記轉換為“ 28.08.2017 03:59:55.0007”到std :: chrono :: system_clock :: time_point。 有什么方法可以通過使用標准庫或boost實現這一目標嗎? 謝謝。

我會利用霍華德·辛南特(Howard Hinnant)的日期庫https://howardhinnant.github.io/date/date.html

例如:

std::stringstream str( "28.08.2017 03:59:55.0007" );
str.imbue( std::locale() );
std::chrono::time_point< std::chrono::system_clock, std::chrono::microseconds > result;
date::from_stream( str, "%d.%m.%Y %H:%M:%S", result );
std::cout << result.time_since_epoch().count();

一種實現可以是:

#include <ctime>
#include <cmath>
#include <chrono>
#include <string>
#include <cstdint>
#include <stdexcept>

std::chrono::system_clock::time_point parse_my_timestamp(std::string const& timestamp) {
    auto error = [&timestamp]() { throw std::invalid_argument("Invalid timestamp: "  + timestamp); };
    std::tm tm;
    auto fraction = ::strptime(timestamp.c_str(), "%d.%m.%Y %H:%M:%S", &tm);
    if(!fraction)
        error();
    std::chrono::nanoseconds ns(0);
    if('.' == *fraction) {
        ++fraction;
        char* fraction_end = 0;
        std::chrono::nanoseconds fraction_value(std::strtoul(fraction, &fraction_end, 10));
        if(fraction_end != timestamp.data() + timestamp.size())
            error();
        auto fraction_len = fraction_end - fraction;
        if(fraction_len > 9)
            error();
        ns = fraction_value * static_cast<std::int32_t>(std::pow(10, 9 - fraction_len));
    }
    else if(fraction != timestamp.data() + timestamp.size())
        error();
    auto seconds_since_epoch = std::mktime(&tm); // Assumes timestamp is in localtime. For UTC use timegm.
    auto timepoint_ns = std::chrono::system_clock::from_time_t(seconds_since_epoch) + ns;
    return std::chrono::time_point_cast<std::chrono::system_clock::duration>(timepoint_ns);
}

我以為我要添加一個答案,因為沒有一個可以專門使用該標准。
給定輸入: istringstream timestamp("28.08.2017 03:59:55.0007") ,可以將其通過get_time轉換為tm ,但是要保留分數秒。 小數秒將需要手動轉換(這可以通過將四舍五入后的余數除以micro比率來構造chrono::microseconds來完成。)所有這些都可以合並為以下內容:

tm tmb;
double r;

timestamp >> get_time(&tmb, "%d.%m.%Y %T") >> r;

const auto output = chrono::time_point_cast<chrono::microseconds>(chrono::system_clock::from_time_t(mktime(&tmb))) + chrono::microseconds(lround(r * micro::den));

現場例子

暫無
暫無

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

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