C++ 使用 std::get_time 解析 YYMMDD ISO 8601 日期字符串会产生意外结果?
C++ parsing YYMMDD ISO 8601 date string with std::get_time gives unexpected result?
我正在尝试解析格式为 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
格式字符串有问题吗?
这不是错误。您已 运行 成为 Y2K 的神器。 std::tm
结构中的 tm_year
字段包含自 1900 年以来的年数。因此,自然而然地,无论您获得什么年份值,都将添加到 1900 年。像 date
这样的古代工具实际上确实遵循POSIX 相应的规范和行为:
date -d'27 JUN 69' +%Y
1969
date -d'27 JUN 68' +%Y
2068
您可以这样使用 Howard Hinnant's free, open-source date/time library:
#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';
}
它适用于 gcc 6.1:http://melpon.org/wandbox/permlink/gy3wpMXeCoxk9Ykj(以及其他平台)。除了正确的输出是:
Tue Dec 3 00:00:00 2019
我正在尝试解析格式为 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
格式字符串有问题吗?
这不是错误。您已 运行 成为 Y2K 的神器。 std::tm
结构中的 tm_year
字段包含自 1900 年以来的年数。因此,自然而然地,无论您获得什么年份值,都将添加到 1900 年。像 date
这样的古代工具实际上确实遵循POSIX 相应的规范和行为:
date -d'27 JUN 69' +%Y
1969
date -d'27 JUN 68' +%Y
2068
您可以这样使用 Howard Hinnant's free, open-source date/time library:
#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';
}
它适用于 gcc 6.1:http://melpon.org/wandbox/permlink/gy3wpMXeCoxk9Ykj(以及其他平台)。除了正确的输出是:
Tue Dec 3 00:00:00 2019