Files
bodyWeight/miniprogram/utils/idCard/index.ts
T

55 lines
1.8 KiB
TypeScript

import type { IdCardParsed } from './types'
/** 校验身份证号格式是否合法 */
export const isIdCardValid = (idCard: string): boolean => {
if (idCard.length !== 18) return false
// 前 17 位必须为数字
if (!/^\d{17}$/.test(idCard.slice(0, 17))) return false
// 第 18 位为数字或 X
if (!/^[\dXx]$/.test(idCard[17])) return false
return true
}
/** 解析身份证号,提取性别、年龄、生日 */
export const parseIdCard = (idCard: string): IdCardParsed => {
const empty: IdCardParsed = { gender: '', age: '', birthday: '', sex: 0 }
if (!isIdCardValid(idCard)) return empty
// 第 17 位奇数为男,偶数为女
const sexCode = parseInt(idCard[16], 10)
const sex = sexCode % 2 === 1 ? 1 : 2
// 第 7-14 位为生日 YYYYMMDD
const year = parseInt(idCard.slice(6, 10), 10)
const month = parseInt(idCard.slice(10, 12), 10)
const day = parseInt(idCard.slice(12, 14), 10)
// 计算年龄
const now = new Date()
let age = now.getFullYear() - year
if (now.getMonth() < month - 1 || (now.getMonth() === month - 1 && now.getDate() < day)) {
age--
}
return {
gender: sex === 1 ? '男' : '女',
age: String(age),
birthday: `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`,
sex,
}
}
/** 从生日字符串(YYYY-MM-DD)计算周岁 */
export const calcAge = (birthday: string): number => {
if (!birthday) return 0
const parts = birthday.split('-').map(Number)
const [year, month, day] = parts
if (!year || !month || !day) return 0
const now = new Date()
let age = now.getFullYear() - year
const nowMonth = now.getMonth() + 1
const nowDay = now.getDate()
if (nowMonth < month || (nowMonth === month && nowDay < day)) age -= 1
return Math.max(0, age)
}