This is a question about invalid input, not invalid formatting. For example given the following code:
tm bar;
foo >> get_time(&bar, "%Y-%m-%d");
cout >> bar.tm_year >> bar.tm_mon >> bar.tm_mday >> endl;
This is fine if I define: stringstream foo("2001-02-28 non-leap year");
And has a clear error if I have invalid format such as: stringstream foo("bad format 2001-02-28 non-leap year");
But I don't know how to detect if my input was invalid for example:
stringstream foo("2001-02-30 non-leap year");
In this case bar
can be read as though nothing was wrong. Is there something I can listen for which will alert me that the input was invalid?
As is mentioned by Matteo Italia's answer, apart from writing your own Gregorian validator, your only reliable double check is
mktime
.tm
s obtained withget_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 thoroughmktime
:While doing this:
istringstream("2001-13-30") >> get_time(&bar, "%Y-%m-%d");
results in a result that would not change when run throughmktime
:In order to have all invalid dates altered by
mktime
we need to read the date in without the use ofget_time
:At this point any error in
bar
may be corrected bymktime
so our actual validation step will be to check for a non-time_t(-1)
return and compare the modifiedbar
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 tobar
was valid.In conclusion, it is possible to validate a
tm
without writing a Gregorian validator, but it is not possible to validate atm
that has been read in byget_time
.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 anmktime
followed by alocaltime
, if you get different values back it means that the original ones were not valid.