主要思路:
1. 根据 YYYYMMDD 截取年、月、日;
2. 判断月是否在 [1,12] 内;
3. 判断各个月的天数是否正确(闰年的二月要另外考虑).
代码:
// 是否为闰年
bool isLeapYear(int year) {
if (year % 400 == 0) return true;
if (year % 4 == 0 && year % 100 != 0) return true;
return false;
}
// YYYYMMDD 是否为有效日期
bool isValidDay(const string& birthday) {
char cy[5];
char cm[3];
char cd[3];
memset(cy, '\0', 5);
memset(cm, '\0', 3);
memset(cd, '\0', 3);
for (int i=0; i<4; i++) {
cy[i] = birthday[i];
}
for (int i=0; i<2; i++) {
cm[i] = birthday[4+i];
}
for (int i=0; i<2; i++) {
cd[i] = birthday[6+i];
}
int year = atoi(cy); // 年
int month = atoi(cm); // 月
int day = atoi(cd); // 日
// 判断月份
if (!(1 <= month && month <= 12)) return false;
// 判断每月的天数是否正确
switch (month) {
case 1:
if (!(1 <= day && day <= 31)) return false;
break;
case 2:
if (isLeapYear(year)) { // 闰年 29 天
if (!(1 <= day && day <= 29)) return false;
} else { // 非闰 28 天
if (!(1 <= day && day <= 28)) return false;
}
break;
case 3:
if (!(1 <= day && day <= 31)) return false;
break;
case 4:
if (!(1 <= day && day <= 30)) return false;
break;
case 5:
if (!(1 <= day && day <= 31)) return false;
break;
case 6:
if (!(1 <= day && day <= 30)) return false;
break;
case 7:
if (!(1 <= day && day <= 31)) return false;
break;
case 8:
if (!(1 <= day && day <= 31)) return false;
break;
case 9:
if (!(1 <= day && day <= 30)) return false;
break;
case 10:
if (!(1 <= day && day <= 31)) return false;
break;
case 11:
if (!(1 <= day && day <= 30)) return false;
break;
case 12:
if (!(1 <= day && day <= 31)) return false;
break;
default:
return false;
}
return true;
}
环境: gcc version 4.6.4 (Ubuntu/Linaro 4.6.4-1ubuntu1~12.04)
更为简明的解法: 《判断 YYYYMMDD 是否为有效日期(UPDATE)》