id-card.ts 1.1 KB

12345678910111213141516171819202122232425262728293031323334
  1. /**
  2. * 从中国大陆 18 位身份证号解析出生日期并计算周岁年龄。
  3. * 号码不足 18 位或出生日期无效时返回 null(不强制校验码,便于输入过程中回填)。
  4. */
  5. export function calcAgeFromChineseIdCard(idCard: string | null | undefined): number | null {
  6. if (!idCard || typeof idCard !== 'string') return null
  7. const s = idCard.trim().toUpperCase()
  8. if (!/^\d{17}[\dX]$/.test(s)) return null
  9. const year = Number(s.slice(6, 10))
  10. const month = Number(s.slice(10, 12))
  11. const day = Number(s.slice(12, 14))
  12. if (!Number.isFinite(year) || !Number.isFinite(month) || !Number.isFinite(day)) return null
  13. if (month < 1 || month > 12 || day < 1 || day > 31) return null
  14. const birth = new Date(year, month - 1, day)
  15. if (
  16. birth.getFullYear() !== year ||
  17. birth.getMonth() !== month - 1 ||
  18. birth.getDate() !== day
  19. ) {
  20. return null
  21. }
  22. const today = new Date()
  23. let age = today.getFullYear() - year
  24. const beforeBirthday =
  25. today.getMonth() < month - 1 ||
  26. (today.getMonth() === month - 1 && today.getDate() < day)
  27. if (beforeBirthday) age -= 1
  28. if (age < 0 || age > 120) return null
  29. return age
  30. }