C ++使用std :: get_time解析YYMMDD ISO 8601日期字符串会产生意外结果吗?

时间:2017-03-21 09:16:55

标签: c++ date-parsing

我试图解析格式为YYMMDD的日期。作为测试,我尝试了以下代码:

#include <iostream>
#include <sstream>
#include <locale>
#include <iomanip>

int main(){
    std::tm t = {};
    std::istringstream ss("191203");
    ss >> std::get_time(&t, "%y%m%d");
    if (ss.fail()){ 
        std::cout << "Parse failed\n";
    } else {
        std::cout << std::put_time(&t, "%c") << '\n';
    }
}

使用Coliru,GCC 6.1(C ++ 17)测试,输出为:

Sun Mar  0 00:00:00 1912

我的期望是:

Mon Dec 3 00:00:00 2019

格式字符串中有什么问题吗?

2 个答案:

答案 0 :(得分:1)

您可以像这样使用Howard Hinnant's free, open-source date/time library

tAr1c1,tAr1c2,tBr1c1,tBr1c2,tBr1c3
tAr2c1,tAr2c2,tBr1c1,tBr1c2,tBr1c3
tAr3c1,tAr3c2,tBr1c1,tBr1c2,tBr1c3

适用于gcc 6.1:http://melpon.org/wandbox/permlink/gy3wpMXeCoxk9Ykj(以及其他平台)。除了正确的输出是:

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

int
main()
{
    date::sys_days t;
    std::istringstream ss("191203");
    ss >> date::parse("%y%m%d", t);
    if (ss.fail())
        std::cout << "Parse failed\n";
    else
        std::cout << date::format("%c", t) << '\n';
}

答案 1 :(得分:0)

这不是一个错误。您已遇到Y2K的工件。 tm_year结构中的std::tm字段包含自1900年以来的年数。因此,无论您获得的年份值是多少都会添加到1900年。像date这样的古代工具实际上遵循POSIX规范和行为相应:

date -d'27 JUN 69' +%Y
1969
date -d'27 JUN 68' +%Y
2068