有没有一种标准的方法可以在不使用Boost的情况下将std::string转换为std::chrono::time_po

Is there a standard way to convert a std::string to std::chrono::time_point without using Boost?

本文关键字:std string Boost 情况下 转换 po time chrono 一种 标准 方法      更新时间:2023-10-16

基本上,我正在寻找一种将类似2014/08/29-11:42:05.042的字符串转换为time_point对象的标准方法。我知道如何用boost来实现,但它只能用STL库来实现吗?怎样

如果能指定类似%y/%m/%d-%H:%M:%S.%f或类似的格式,那就太好了。

好吧,至少对于毫秒分辨率的固定格式来说,这是可行的。试图使此代码能够接受任何字符串格式就像重新发明轮子一样(即Boost.中有用于所有这些的功能

std::chrono::system_clock::time_point string_to_time_point(const std::string &str)
{
    using namespace std;
    using namespace std::chrono;
    int yyyy, mm, dd, HH, MM, SS, fff;
    char scanf_format[] = "%4d.%2d.%2d-%2d.%2d.%2d.%3d";
    sscanf(str.c_str(), scanf_format, &yyyy, &mm, &dd, &HH, &MM, &SS, &fff);
    tm ttm = tm();
    ttm.tm_year = yyyy - 1900; // Year since 1900
    ttm.tm_mon = mm - 1; // Month since January 
    ttm.tm_mday = dd; // Day of the month [1-31]
    ttm.tm_hour = HH; // Hour of the day [00-23]
    ttm.tm_min = MM;
    ttm.tm_sec = SS;
    time_t ttime_t = mktime(&ttm);
    system_clock::time_point time_point_result = std::chrono::system_clock::from_time_t(ttime_t);
    time_point_result += std::chrono::milliseconds(fff);
    return time_point_result;
}
std::string time_point_to_string(std::chrono::system_clock::time_point &tp)
{
    using namespace std;
    using namespace std::chrono;
    auto ttime_t = system_clock::to_time_t(tp);
    auto tp_sec = system_clock::from_time_t(ttime_t);
    milliseconds ms = duration_cast<milliseconds>(tp - tp_sec);
    std::tm * ttm = localtime(&ttime_t);
    char date_time_format[] = "%Y.%m.%d-%H.%M.%S";
    char time_str[] = "yyyy.mm.dd.HH-MM.SS.fff";
    strftime(time_str, strlen(time_str), date_time_format, ttm);
    string result(time_str);
    result.append(".");
    result.append(to_string(ms.count()));
    return result;
}

为了测试它,我这样尝试,并确保字符串正确表示当前日期时间:

auto tp_src = system_clock::now();
string value = time_point_to_string(tp_src);
auto tp_cnv = string_to_time_point(value);
auto error = duration_cast<milliseconds>(tp_src - tp_cnv).count();
Assert::IsTrue(error == 0);