请注意
tm
的成员变量
tm_sec
表示最小的时间增量,它是一个
int
类型,仅在以下范围内定义:
自 C++11 起,每分钟之后的秒数为[0,60]
因此,您将无法在tm
中存储秒的一部分,只需舍弃小数点后面的数字即可。
如Karsten Koop所建议的那样,您可以两次读取年份,第二个%Y
将覆盖第一个。
auto fmt = "%H:%M:%S.%Y %Z %b %d %Y";
实时示例
那么,我建议
不要使用
strptime
,因为它是一个POSIX函数,使用像
get_time
这样的标准函数更可取。这有一个小缺陷:
get_time
没有时区的知识,但
tm
也是如此,除了
tm_isdst
外,它是:
夏令时标志。如果DST生效,则值为正,如果不生效,则为零;如果没有信息,则为负
所以,如果您追求这样的东西,您可能需要单独分配tm_isdst
。
tm tmbuf;
stringstream str("20:48:01.469 UTC MAR 31 2016");
str >> get_time(&tmbuf, "%H:%M:%S.%Y UTC %b %d %Y");
实时示例
我的get_time
答案有点虚伪,因为我虽然谈到了标准化的重要性,但只能在libc++上运行它。因此,我想发布一个更通用的解决方案,它也会丢弃时区,所以你需要独立设置tm_isdst
:
tm tmbuf{};
stringstream str("20:48:01.469 UTC MAR 31 2016");
string tm_mon;
str >> get_time(&tmbuf, "%T");
str.ignore(std::numeric_limits<std::streamsize>::max(), 'C');
str >> tm_mon >> get_time(&tmbuf, "%d %Y");
for (const auto& i : { "JAN"s, "FEB"s, "MAR"s, "APR"s, "MAY"s, "JUN"s, "JUL"s, "AUG"s, "SEP"s, "OCT"s, "NOV"s, "DEC"s }) {
if (equal(cbegin(tm_mon), cend(tm_mon), cbegin(i), cend(i), [](const unsigned char a, const unsigned char b) { return toupper(a) == b; })) break;
++tmbuf.tm_mon;
}
实时示例
这有两个关键依赖:
- 时区总是以字符
'C'
结尾(必须大写)
- 输入的月份缩写必须与我的
initializer_list
中的一个匹配
"%H:%M:%s.%f %Z %b %d %Y"
。 - EdChum"%H:%M:%S.%f %Z %b %d %Y"
- GMichael