在C++ 11中解析毫秒日期时间的最佳方法是什么

Nez*_*ick 12 c++ c++11 c++14

strptime当我们有毫秒时间的日期时间字符串时,下一个最好的事情是什么?

鉴于:

"30/03/09 16:31:32.121"
Run Code Online (Sandbox Code Playgroud)

我们不能使用常规strptime因为struct tm不存储毫秒.是否有新的课程可以实现这一目标?

How*_*ant 6

我会手动解析这些字段(读入int和double的秒数),然后使用days_from_civil将年/月/日转换为chrono::system_clock::time_point:

std::chrono::system_clock::time_point t(days(days_from_civil(y, m, d)));
Run Code Online (Sandbox Code Playgroud)

在哪里days:

using days = std::chrono::duration<int, std::ratio<86400>>;
Run Code Online (Sandbox Code Playgroud)

然后你可以添加小时,分钟和秒.要处理小数秒,你需要做一个轻微的舞蹈:

double s;
your_stream >> s;  // 32.121
using namespace std::chrono;
duration<double> dsecs(s);
seconds sec = duration_cast<seconds>(dsecs);
milliseconds ms = duration_cast<milliseconds>(dsecs - sec);
t += sec + ms;
Run Code Online (Sandbox Code Playgroud)

如果您愿意,可以round在此处使用您的毫秒转换:

milliseconds ms = round<milliseconds>(dsecs - sec);
Run Code Online (Sandbox Code Playgroud)

duration_cast截断为零.还有其他舍入模式:地板,圆形,ceil,在此链接.

将其全部包装在一个简洁的功能中,以便于重复使用.:-)

以上代码均假设为UTC.如果已知您正在解析的日期/时间偏离UTC,则可以添加/减去该偏移量.所有已知的system_clock跟踪Unix时间的实现,这是UTC时区1970-01-01以来的秒数.

更新

自写这个答案以来,我开发了一个更普通的图书馆,当时OP似乎正在寻找.它可以将各种子秒精度直接解析成std::chrono::system_clock::time_point如下:

#include "date/date.h"
#include <iostream>
#include <sstream>

int
main()
{
    std::istringstream in{"30/03/09 16:31:32.121\n"
                          "30/03/09 16:31:32.1214"};
    std::chrono::system_clock::time_point tp;
    in >> date::parse("%d/%m/%y %T", tp);
    using namespace date;
    std::cout << tp << '\n';
    in >> date::parse(" %d/%m/%y %T", tp);
    std::cout << tp << '\n';
}
Run Code Online (Sandbox Code Playgroud)

这输出:

2009-03-30 16:31:32.121000
2009-03-30 16:31:32.121400
Run Code Online (Sandbox Code Playgroud)

这个库使用与我最初描述的相同的技术和工具,但是打包并准备好作为单个头库.