从 std::string 读取时间为 UTC 时间

Haa*_*hii 5 c++ datetime boost c++14

在我的一个程序中,我必须多次阅读几种不同格式的内容。但在所有格式中,时间均以 UTC 给出(即不是我的本地时区)。对于采用日期字符串和格式字符串并输出时间戳的函数来说,最好的方法是什么std::time_t

目前我正在使用boost

#include "boost/date_time/gregorian/gregorian.hpp"
#include "boost/date_time/posix_time/posix_time.hpp"

std::time_t to_timestamp_utc(const std::string& _dateString) {
    using namespace boost::gregorian;
    using namespace boost::posix_time;
    return to_time_t(ptime(from_undelimited_string(_dateString)));
}
Run Code Online (Sandbox Code Playgroud)

但这仅适用于“YYYYMMDD”格式。std::get_time另一方面,标准库函数假定输入日期的格式为我的当地时间而不是 UTC(或者至少我还没有找到更改它的方法)。任何建议都是非常受欢迎的。

当前的解决方案基于 Maxim Egorushkin 建议。

std::time_t utc_to_timestamp(const std::string& _dateString, const std::string& _format) {
    // Set sec, min, hour to zero in case the format does not provide those
    std::tm timeStruct;
    timeStruct.tm_sec = 0;
    timeStruct.tm_min = 0;
    timeStruct.tm_hour = 0;
    char* const result = strptime(_dateString.c_str(), _format.c_str(), &timeStruct);
    // Throw exception if format did not work
    REQUIRE(result == _dateString.c_str()+_dateString.size(), "Failed to parse dateTime.");
    return timegm(&timeStruct);
}
Run Code Online (Sandbox Code Playgroud)

How*_*ant 4

这是一个免费的开源 C++11/14 库,其中的parse函数采用std::basic_istream<CharT, Traits>、格式字符串 ( std::basic_string<CharT, Traits>) 和std::chrono::time_point<system_clock, seconds>.

template <class CharT, class Traits, class Duration>
void
parse(std::basic_istream<CharT, Traits>& is,
      const std::basic_string<CharT, Traits>& format, sys_time<Duration>& tp);
Run Code Online (Sandbox Code Playgroud)

你像这样使用它:

std::istringstream in{"2014-11-12 19:12:14"};
date::sys_seconds tp;
in >> date::parse("%F %T", tp);
Run Code Online (Sandbox Code Playgroud)

如果failbit退出时未设置,tp则为Unix 时间,精度为秒。您可以将其转换为time_t如下所示:

time_t t = system_clock::to_time_t(tp);
Run Code Online (Sandbox Code Playgroud)

或者你可以直接打印出来:

cout << tp.time_since_epoch().count() << '\n';
Run Code Online (Sandbox Code Playgroud)

如果您确实failbit设置好了,则可以使用其他格式字符串重试。

如果您的时间戳具有亚秒精度,这也将处理亚秒精度。所有输出都将为 UTC,因为这是一个类型安全库,其中time_point<system_clock, whatever-duration> 表示UTC (技术上它表示Unix Time)。该库还有一种解析当地时间的方法。

如果您的格式不明确,则可能会成功并返回错误的值,从而使您尝试格式的顺序变得很重要。