std::get_time on Visual 2015 does not fail on incorrect date

我们两清 提交于 2019-12-23 18:28:13

问题


I'm executing the following code on Windows with Visual Studio 2015. Basically I use std::get_time to parse a date, but when the date is invalid, for example, a day greater than 31, it does not seem to set the fail bit on the stream.

I have tried this on Ubuntu with g++ 5.4.0 and it sets the fail bit and prints "Parsing failed!". Is this a bug on Windows or am I doing something wrong.

Thanks in advance!

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;
}

回答1:


You can use Howard Hinnant's free, open-source header-only datetime library on Windows to give you the desired behavior. The syntax is only slightly different, and it is much easier to use, and compatible with <chrono>. It is also better documented and specified than the time-parsing parts of the C++ standard.

#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();
    }
}

Output:

Parsing failed!

This library also works with g++ 5.4.0 and clang.

You can also simplify your format down to "%F %T", and it can also work with subsecond precision if desired.




回答2:


Welcome to the world of the grey zone of the standard! std::get_time (various overloads) is specified in chapters 22 Localization library, and 27 Input/output library of the standard.

AFAIK, the standard requires:

  • if the input string correctly describes a valid date in valid format, the std::tm object is populated accordingly
  • if the input string cannot be parsed, the fail bit on the input string shall be set

But here, the input string can be parsed, and some implementations can assume that the march 32 is just the april 1. Said differently it is unspecified by standard what controls an implementation shall do on the input value. A non numeric day shall give an error, but this is implementation dependant.



来源:https://stackoverflow.com/questions/43235953/stdget-time-on-visual-2015-does-not-fail-on-incorrect-date

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!