std::get_time 在 Visual 2015 上不会在不正确的日期失败
std::get_time on Visual 2015 does not fail on incorrect date
我在 Windows 和 Visual Studio 2015 上执行以下代码。基本上我使用 std::get_time
来解析日期,但是当日期无效时,例如, day 大于 31,它似乎没有在流上设置失败位。
我已经在 Ubuntu 上用 g++ 5.4.0 试过了,它设置了失败位并打印 "Parsing failed!"。这是 Windows 上的错误还是我做错了什么。
提前致谢!
std::string date = "2019-2-37 23:00:00"; // day (37) is wrong.
std::string format = "%Y-%m-%d %H:%M:%S";
std::tm tm_object{};
std::istringstream input(date);
input.imbue(std::locale(std::setlocale(LC_ALL, nullptr)));
input >> std::get_time(&tm_object, format.c_str());
if (input.fail())
{
std::cout << "Parsing failed!";
}
else
{
std::cout << "Parsing ok!\n";
std::cout << "Day is : " << tm_object.tm_mday;
}
欢迎来到标准灰色地带的世界! std::get_time
(各种重载)在标准的第 22 章本地化库和第 27 Input/output 库中指定。
据我所知,标准要求:
- 如果输入字符串正确描述了有效格式的有效日期,
std::tm
对象会相应地填充
- 如果无法解析输入字符串,则设置输入字符串的失败位
但是在这里,可以解析输入字符串,并且一些实现可以假定 3 月 32 日就是 4 月 1 日。换句话说,标准未指定控制实现对输入值执行的操作。非数字日期会出错,但这取决于实现。
您可以在 Windows 上使用 Howard Hinnant's free, open-source header-only datetime library 以获得所需的行为。语法仅略有不同,使用起来更容易,并且与 <chrono>
兼容。它也比 C++ 标准的时间解析部分更好地记录和指定。
#include "date.h"
#include <iostream>
#include <sstream>
#include <string>
int
main()
{
std::string date = "2019-2-37 23:00:00"; // day (37) is wrong.
std::string format = "%Y-%m-%d %H:%M:%S";
date::sys_seconds tm_object{};
std::istringstream input(date);
input >> date::parse(format, tm_object);
if (input.fail())
{
std::cout << "Parsing failed!";
}
else
{
std::cout << "Parsing ok!\n";
date::year_month_day ymd = date::floor<date::days>(tm_object);
std::cout << "Day is : " << ymd.day();
}
}
输出:
Parsing failed!
这个库也适用于 g++ 5.4.0 和 clang。
您还可以将 format
简化为 "%F %T"
,如果需要,它还可以使用亚秒级精度。
我在 Windows 和 Visual Studio 2015 上执行以下代码。基本上我使用 std::get_time
来解析日期,但是当日期无效时,例如, day 大于 31,它似乎没有在流上设置失败位。
我已经在 Ubuntu 上用 g++ 5.4.0 试过了,它设置了失败位并打印 "Parsing failed!"。这是 Windows 上的错误还是我做错了什么。
提前致谢!
std::string date = "2019-2-37 23:00:00"; // day (37) is wrong.
std::string format = "%Y-%m-%d %H:%M:%S";
std::tm tm_object{};
std::istringstream input(date);
input.imbue(std::locale(std::setlocale(LC_ALL, nullptr)));
input >> std::get_time(&tm_object, format.c_str());
if (input.fail())
{
std::cout << "Parsing failed!";
}
else
{
std::cout << "Parsing ok!\n";
std::cout << "Day is : " << tm_object.tm_mday;
}
欢迎来到标准灰色地带的世界! std::get_time
(各种重载)在标准的第 22 章本地化库和第 27 Input/output 库中指定。
据我所知,标准要求:
- 如果输入字符串正确描述了有效格式的有效日期,
std::tm
对象会相应地填充 - 如果无法解析输入字符串,则设置输入字符串的失败位
但是在这里,可以解析输入字符串,并且一些实现可以假定 3 月 32 日就是 4 月 1 日。换句话说,标准未指定控制实现对输入值执行的操作。非数字日期会出错,但这取决于实现。
您可以在 Windows 上使用 Howard Hinnant's free, open-source header-only datetime library 以获得所需的行为。语法仅略有不同,使用起来更容易,并且与 <chrono>
兼容。它也比 C++ 标准的时间解析部分更好地记录和指定。
#include "date.h"
#include <iostream>
#include <sstream>
#include <string>
int
main()
{
std::string date = "2019-2-37 23:00:00"; // day (37) is wrong.
std::string format = "%Y-%m-%d %H:%M:%S";
date::sys_seconds tm_object{};
std::istringstream input(date);
input >> date::parse(format, tm_object);
if (input.fail())
{
std::cout << "Parsing failed!";
}
else
{
std::cout << "Parsing ok!\n";
date::year_month_day ymd = date::floor<date::days>(tm_object);
std::cout << "Day is : " << ymd.day();
}
}
输出:
Parsing failed!
这个库也适用于 g++ 5.4.0 和 clang。
您还可以将 format
简化为 "%F %T"
,如果需要,它还可以使用亚秒级精度。