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

时间:2016-08-11 13:21:42

标签: 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)));
}

但这仅适用于" 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);
}

2 个答案:

答案 0 :(得分:3)

以下是free, open-source C++11/14 library 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);

你这样使用它:

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

如果退出时未设置failbit,则tp将为Unix Time,精确度为秒。您可以将其转换为time_t,如此:

time_t t = system_clock::to_time_t(tp);

或者你可以打印出来:

cout << tp.time_since_epoch().count() << '\n';

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

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

如果您的格式不明确,那么可能会成功并返回错误的值,从而使您尝试格式的顺序显着。

答案 1 :(得分:2)

如果您事先知道可能的格式,可以使用strptime函数找到成功解析字符串的格式。它会返回struct tm,您将其视为已分解的UTC并将其传递到timegm以获取time_t