This is a question about invalid input, not invalid formatting. For example given the following code:
tm bar;
foo >> get_time(&bar, \"%Y-
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 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
.
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.