当我们的日期时间字符串为毫秒时,strptime
的下一个最佳选择是什么?
假设:
"30/03/09 16:31:32.121"
我们无法使用常规strptime,因为struct tm
不会存储毫秒数。是否有新的课程可以实现这一目标?
答案 0 :(得分:6)
我会手动解析这些字段(读入int并加倍秒),然后使用days_from_civil将年/月/日转换为chrono::system_clock::time_point
:
std::chrono::system_clock::time_point t(days(days_from_civil(y, m, d)));
其中days
是:
using days = std::chrono::duration<int, std::ratio<86400>>;
然后你可以添加小时,分钟和秒。要处理小数秒,你需要做一个轻微的舞蹈:
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;
如果您愿意,请使用round
from here进行毫秒转换:
milliseconds ms = round<milliseconds>(dsecs - sec);
duration_cast
截断为零。还有其他的舍入模式:floor,round,ceil,at this link。
将其全部包装在一个简洁的功能中,以便于重复使用。 : - )
以上代码均假设为UTC。如果已知您正在解析的日期/时间偏离UTC,则可以添加/减去该偏移量。 system_clock
跟踪Unix time的所有已知实现,这是UTC时区1970-01-01以来的秒数。
<强>更新强>
自从写完这个答案以来,我已经开发了一个more general library,当时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';
}
输出:
2009-03-30 16:31:32.121000
2009-03-30 16:31:32.121400
此库使用与我最初描述的相同的技术和工具,但已打包并准备作为单个头库。