首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >验证某人的SA ID号的出生日期

验证某人的SA ID号的出生日期
EN

Stack Overflow用户
提问于 2022-10-12 16:44:03
回答 2查看 57关注 0票数 2

我试图从某人的身份证号码中提取出生日期,并确保特定月份的天数是准确的,例如:如果二月有29天以上,它应该返回false,但它返回的是true。我想我只是需要一双全新的眼睛来研究这个密码。

代码语言:javascript
复制
function checkDateOfBirth(idNumber) {
    const year = idNumber.substring(0, 2);
    const month = idNumber.substring(2, 4);
    const day = idNumber.substring(4, 6);
    let isDOBValid = false;
    const dateRegex = /^([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[0-1]))$/;
    const cutOffDate = new Date().getFullYear() - 2000;
    const fullDate =
        (year > cutOffDate ? "19" : "20") + year + "-" + month + "-" + day;

    if (
        day > 31 ||
        month > 12 ||
        (month == 2 && day > 29) ||
        ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30)
    ) {
        isDOBValid;
    } else {
        isDOBValid = true;
    }

    if (dateRegex.test(fullDate) == false) {
        isDOBValid;
    } else if (dateRegex.test(fullDate) == true) {
        isDOBValid = true;
    }
    return isDOBValid;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-12 18:09:49

一些改进

让我首先提出几个简化的建议。

首先,让我们从第二个if语句开始。if语句的目的是检查布尔值。因为dateRegex.test(fullDate)已经返回了一个布尔值,所以您可以直接将它传递给if语句。现在,如果要检查布尔值是否为false而不是true,只需在开始时使用逻辑不(又称否定)运算符(!)来翻转它。它将把false转换为true,而vis则反过来。您也可以将您的else if替换为else,因为如果它不是false,那么它必须是true

代码语言:javascript
复制
if (!dateRegex.test(fullDate)) {
  isDOBValid;
} else {
  isDOBValid = true;
}

第二,实际上可以在这两种情况下完全消除if块。isDOBValid;这一行绝对什么也不做。因为我们只需要else块中的逻辑,所以我们可以简单地将这个逻辑移动到if块,然后像以前一样否定条件。对于第一个if语句,我们可以像以前那样添加逻辑NOT运算符,或者只转换所有条件。我会倒置所有的条件,仅仅因为我认为它看起来更好。然后对于第二个,我们可以移除我们之前放在那里的操作符。

代码语言:javascript
复制
if (
  day < 31 &&
  month < 12 &&
  (month != 2 && day <= 29) ||
  ((month != 4 && month != 6 && month != 9 && month != 11) && day <= 30)
) {
  isDOBValid = true;
}

if (dateRegex.test(fullDate)) {
  isDOBValid = true;
}

问题

代码的实际问题还在于您的if语句。他们根本就没有联系。您只有一个布尔值(isDOBValid),这两个if语句都设置为两个完全不同的条件。因为它是自上而下执行的,所以第二个条件优先。这意味着,无论是哪一天/月/年,如果正则表达式成功匹配,您的函数将始终返回true。要解决这个问题,您需要连接它们。有几种方法可以做到这一点。

首先,你可以把他们锁起来。

代码语言:javascript
复制
if (
  day < 31 &&
  month < 12 &&
  (month != 2 && day <= 29) ||
  ((month != 4 && month != 6 && month != 9 && month != 11) && day <= 30)
) {
  if (dateRegex.test(fullDate)) {
    isDOBValid = true;
  }
}

这确保只有在第一个条件成功时才运行第二个条件。

其次,您可以检查正在设置的变量。

代码语言:javascript
复制
if (
  day < 31 &&
  month < 12 &&
  (month != 2 && day <= 29) ||
  ((month != 4 && month != 6 && month != 9 && month != 11) && day <= 30)
) {
  isDOBValid = true;
}

if (dateRegex.test(fullDate) && isDOBValid) {
  isDOBValid = true;
}
else{
  isDOBValid = false;
}

这实际上与最后一个相同,只是嵌套较少。在这种情况下,您还需要else块,否则就会遇到相反的问题。如果没有else,如果isDOBValidtrue,但是正则表达式不匹配,那么函数无论如何都会返回true,因为isDOBValid在前面的语句中被设置为true

您还可以修改前面的代码片段,使这两个if语句相互矛盾。这可以通过简单地反转第二个条件,然后将isDOBValid设置为if块中的false来完成。

代码语言:javascript
复制
if (
  day < 31 &&
  month < 12 &&
  (month != 2 && day <= 29) ||
  ((month != 4 && month != 6 && month != 9 && month != 11) && day <= 30)
) {
  isDOBValid = true;
}

if (!dateRegex.test(fullDate)) {
  isDOBValid = false;
}

这确保了您的两个检查都必须通过,才能使isDOBValid成为true

最后,到目前为止,最好的解决方案是抛弃正则表达式,手动检查日/月组合,只需使用内置的JavaScript方法即可。最简单的方法是使用Date类。这个类会捕获任何无效的日期,但是我们仍然需要小心闰年。例如,如果要运行new Date("02/31/2016"),则日期仍将被解析,但解析的结果将是3/02/2016而不是02/31/2016。这很简单,但是我们可以检查它给我们的月份是否是我们给它的那个月。如果不是,日期是无效的。我们可以使用Date.getDate()函数获得日期。但是它给我们的月份是基于0的,所以我们需要添加1才能得到实际的月份。这个函数的另一个重要部分是,如果日期无效,它只会给我们提供NaN,这也是非常容易检查的。因此,使用这个类,我们所需要做的就是检查月份,以确保日期是有效的。如果它不是NaN,并且与我们给它的相同,那么它是有效的。

现在,我们只需要将我们所拥有的转换成有效的日期格式。这非常容易,因为我们已经有了独立的月、日和年,所以我们只需将其转换为MM/dd/yy格式,只需在两者之间连接一个/即可。您的整个功能将简化为:

代码语言:javascript
复制
function checkDateOfBirth(idNumber) {
  const year = idNumber.substring(0, 2);
  const month = idNumber.substring(2, 4);
  const day = idNumber.substring(4, 6);

  var date = new Date(month + "/" + day + "/" + year);
  return !isNaN(date.getMonth()) && date.getMonth() + 1 == month;
}

console.log(checkDateOfBirth("160230"));
console.log(checkDateOfBirth("050625"));
console.log(checkDateOfBirth("100431"));

票数 2
EN

Stack Overflow用户

发布于 2022-10-12 17:29:38

我跟踪@杰西的评论,它运行的很好。您需要检查regex只有当天,月和年是好的。

代码语言:javascript
复制
console.log(checkDateOfBirth("890230"));

function checkDateOfBirth(idNumber) {
    const year = idNumber.substring(0, 2);
    const month = idNumber.substring(2, 4);
    const day = idNumber.substring(4, 6);
    let isDOBValid = false;
    const dateRegex = /^([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[0-1]))$/;
    const cutOffDate = new Date().getFullYear() - 2000;
    const fullDate =
        (year > cutOffDate ? "19" : "20") + year + "-" + month + "-" + day;

    if (day > 31 || month > 12) {
        isDOBValid = false;
    } else if (month == 2 && day > 29) {
        isDOBValid = false;
    } else if ((month == (4 || 6 || 9 || 11)) && day > 30) {
        isDOBValid = false;
    } else {
        if (dateRegex.test(fullDate) == false) {
            isDOBValid;
        } else if (dateRegex.test(fullDate) == true) {
            isDOBValid = true;
        }
    }
    return isDOBValid;
}

我希望它能帮到你。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74045351

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档