古老的榕树

Go 通过身份证号获取生日年龄性别

潘军杰 发表于 2018-06-22 21:02 阅读(5847) 评论(4) 赞(3)

我记得之前看到一个 Java 版本,通过身份证号获取出生日期,年龄和性别这些有用的信息,但一时记不起具体出处了,因为现在的项目都采用了 Go 开发,找了相关的库,竟然找不到,现在想用 Go 实现一个,自己动手丰衣足食,身份证号的位数代表的含义,通过百度百科可以查到,这是关键点,不再累赘说明,代码里说吧

//中国居民身份证 工具类
//仅仅适用于18位数的身份证
//通过身份证号,获取出生年份,月份,日,和性别,生日,年龄

package util

import (
	"log"
	"strconv"
	"time"
)

type IDCardInfo struct {
	IDCardNo string
	Year     string
	Month    string
	Day      string
	BirthDay string
	Sex      uint
	Age      uint
}

//实例化居民身份证结构体
func NewIDCard(IDCardNo string) *IDCardInfo {
	if IDCardNo == "" || len(IDCardNo) != 18 {
		return nil
	}

	ins := IDCardInfo{
		IDCardNo: IDCardNo,
	}

	ins.Year = ins.GetYear()
	ins.Month = ins.GetMonth()
	ins.Day = ins.GetDay()
	ins.Sex = ins.GetSex()
	ins.BirthDay = ins.GetBirthDayStr()
	ins.Age = ins.GetAge()

	return &ins
}

//根据身份证号获取生日(时间格式)
func (s *IDCardInfo) GetBirthDay() *time.Time {
	if s == nil {
		return nil
	}

	dayStr := s.IDCardNo[6:14] + "000001"
	birthDay, err := time.Parse("20060102150405", dayStr)
	if err != nil {
		log.Fatal(err)
		return nil
	}

	return &birthDay
}

//根据身份证号获取生日(字符串格式 yyyy-MM-dd HH:mm:ss)
func (s *IDCardInfo) GetBirthDayStr() string {
	defaultDate := "1999-01-01 00:00:01"
	if s == nil {
		return defaultDate
	}

	birthDay := s.GetBirthDay()
	if birthDay == nil {
		return defaultDate
	}

	return birthDay.Format("2006-01-02 15:04:05")
}

//根据身份证号获取生日的年份
func (s *IDCardInfo) GetYear() string {
	if s == nil {
		return ""
	}

	return s.IDCardNo[6:10]
}

//根据身份证号获取生日的月份
func (s *IDCardInfo) GetMonth() string {
	if s == nil {
		return ""
	}

	return s.IDCardNo[10:12]
}

//根据身份证号获取生日的日份
func (s *IDCardInfo) GetDay() string {
	if s == nil {
		return ""
	}

	return s.IDCardNo[12:14]
}

//根据身份证号获取性别
func (s *IDCardInfo) GetSex() uint {
	var unknown uint = 3
	if s == nil {
		return unknown
	}

	sexStr := s.IDCardNo[16:17]
	if sexStr == "" {
		return unknown
	}

	i, err := strconv.Atoi(sexStr)
	if err != nil {
		return unknown
	}

	if i%2 != 0 {
		return 1
	}

	return 0
}

//根据身份证号获取年龄
func (s *IDCardInfo) GetAge() uint {
	if s == nil {
		return 19
	}

	birthDay := s.GetBirthDay()
	if birthDay == nil {
		return 19
	}

	now := time.Now()

	age := now.Year() - birthDay.Year()
	if now.Month() < birthDay.Month() {
		age = age - 1
	}

	if age <= 0 {
		return 19
	}

	if age <= 0 || age >= 150 {
		return 19
	}

	return uint(age)
}


(完)


4 条网友评论

1 楼: 你好 发表于 2021-04-07 11:02:38   回复 TA

这里逻辑错了 if now.Month() > birthDay.Month() { age = age - 1 } 应该修改成 if now.Month() > birthDay.Month() { age = age + 1 }

2 楼: 你好 发表于 2021-04-07 11:04:20   回复 TA

而且,这里也应该修改成age := now.Year() - birthDay.Year() - 1

3 楼: 潘军杰 (博主) 发表于 2021-08-19 16:17:22   回复 TA

引用"你好"的评论

这里逻辑错了 if now.Month() > birthDay.Month() { age = age - 1 } 应该修改成 if now.Month() > birthDay.Month() { age = age + 1 }
非常感谢,你的发现和更正,我再验证一下问题,修改过来!

4 楼: 潘军杰 (博主) 发表于 2021-08-19 16:31:07   回复 TA

引用"你好"的评论

这里逻辑错了 if now.Month() > birthDay.Month() { age = age - 1 } 应该修改成 if now.Month() > birthDay.Month() { age = age + 1 }
经过检验,缺失是判断逻辑相反了,只需更改 if now.Month() > birthDay.Month() 代码为 if now.Month() < birthDay.Month() 即可,其他不用修改!非常感谢!
称呼*
邮箱*
内容*
验证码*
验证码 看不清换张