How Can I Tell if My struct tm Has Been Left in an Invalid State?

后端 未结 2 1768
醉酒成梦
醉酒成梦 2020-12-21 10:49

This is a question about invalid input, not invalid formatting. For example given the following code:

tm bar;

foo >> get_time(&bar, \"%Y-         


        
相关标签:
2条回答
  • 2020-12-21 11:17

    As is mentioned by Matteo Italia's answer, apart from writing your own Gregorian validator, your only reliable double check is mktime. tms obtained with get_time cannot be validated, as fields may and may not be filled out. Consider the following 2 invalid examples:

    Doing this: istringstream("2001-02-30") >> get_time(&bar, "%Y-%m-%d"); results in a result that would change when run thorough mktime:

    bar.tm_mday : 30
    bar.tm_mon : 1
    bar.tm_year : 100

    While doing this: istringstream("2001-13-30") >> get_time(&bar, "%Y-%m-%d"); results in a result that would not change when run through mktime:

    bar.tm_mday : 13
    bar.tm_mon : 0
    bar.tm_year : 100

    In order to have all invalid dates altered by mktime we need to read the date in without the use of get_time:

    int year;
    int month;
    int day;
    istringstream foo("2000-13-30");
    
    foo >> year >> ws;
    foo.ignore();
    foo >> month >> ws;
    foo.ignore();
    foo >> day;
    
    tm bar = { 0, 0, 0, day, month - 1, year - 1900 };
    

    At this point any error in bar may be corrected by mktime so our actual validation step will be to check for a non-time_t(-1) return and compare the modified bar back to the original values: if(time_t(-1) != mktime(&bar) && bar.tm_mday == day && bar.tm_mon == month - 1 && bar.tm_year == year - 1900) if this condition is true then the input to bar was valid.

    In conclusion, it is possible to validate a tm without writing a Gregorian validator, but it is not possible to validate a tm that has been read in by get_time.

    0 讨论(0)
  • 2020-12-21 11:31

    Since mktime tries to interpret also out-of-range values (i.e. for 2001-02-30 will be interpreted as 2001-03-01), you can do an mktime followed by a localtime, if you get different values back it means that the original ones were not valid.

    0 讨论(0)
提交回复
热议问题