正如Matteo Italia的回答所提到的,除了编写自己的公历验证器之外,您唯一可靠的双重检查是mktime
. tm
获得的 sget_time
无法验证,因为可能会也可能不会填写字段。考虑以下 2 个无效示例:
这样做:istringstream("2001-02-30") >> get_time(&bar, "%Y-%m-%d");
结果会在彻底运行时发生变化mktime
:
bar.tm_mday
: 30
bar.tm_mon
: 1
bar.tm_year
: 100
执行此操作时:istringstream("2001-13-30") >> get_time(&bar, "%Y-%m-%d");
导致运行时不会改变的结果mktime
:
bar.tm_mday
: 13
bar.tm_mon
: 0
bar.tm_year
: 100
为了更改所有无效日期,mktime
我们需要在不使用的情况下读取日期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 };
此时,任何错误都bar
可以被纠正,mktime
因此我们的实际验证步骤将是检查非time_t(-1)
返回并将修改bar
后的值与原始值进行比较:
if(time_t(-1) != mktime(&bar) && bar.tm_mday == day && bar.tm_mon == month - 1 && bar.tm_year == year - 1900)
如果此条件为真,则输入bar
有效。
总之,可以在tm
不编写 Gregorian 验证器的情况下验证 a,但无法验证tm
已被 读入的a get_time
。