C#根据身份证号码,计算生日、年龄、性别

朋友谈及身份证相关的信息,才了解到原来省份证号码中包含了年龄和性别。

这样在数据库中,就不必单独留字段存放它们了(不过,要根据具体情况来,要是读取频率较高,还是单独列出为好),这样顺带解决了年龄变更的问题。

程序仅仅为了实现这个功能,里面还是需要数据验证的,用户输入的信息,毕竟在猿类看来,都是“非法的”。废话不多说了,贴上我写的程序,还请路过的大神斧正:

复制代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace calculateAgeBirthdatSexDemo
{
    public class Program
    {
        public static void Main(string[] args)
        {
            string identityCard = "32128119930718125X";//随便拼的,如有雷同,纯属搞怪哈
            BirthdayAgeSex entity = new BirthdayAgeSex();
            entity=GetBirthdayAgeSex(identityCard);
            if (entity != null)
            {
                Console.WriteLine(entity.Birthday + "-----" + entity.Sex + "-----" + entity.Age);
            }
            Console.ReadLine();
        }

        public static BirthdayAgeSex GetBirthdayAgeSex(string identityCard)
        {
            if (string.IsNullOrEmpty(identityCard))
            {
                return null;
            }
            else
            {
                if (identityCard.Length != 15 && identityCard.Length != 18)//身份证号码只能为15位或18位其它不合法
                {
                    return null;
                }
            }

            BirthdayAgeSex entity = new BirthdayAgeSex();
            string strSex = string.Empty;
            if (identityCard.Length == 18)//处理18位的身份证号码从号码中得到生日和性别代码
            {
                entity.Birthday = identityCard.Substring(6, 4) + "-" + identityCard.Substring(10, 2) + "-" + identityCard.Substring(12, 2);
                strSex = identityCard.Substring(14, 3);
            }
            if (identityCard.Length == 15)
            {
                entity.Birthday = "19" + identityCard.Substring(6, 2) + "-" + identityCard.Substring(8, 2) + "-" + identityCard.Substring(10, 2);
                strSex = identityCard.Substring(12, 3);
            }
            
            entity.Age = CalculateAge(entity.Birthday);//根据生日计算年龄
            if (int.Parse(strSex) % 2 == 0)//性别代码为偶数是女性奇数为男性
            {
                entity.Sex = "女";
            }
            else
            {
                entity.Sex = "男";
            }
            return entity;
        }

        /// <summary>
        /// 根据出生日期,计算精确的年龄
        /// </summary>
        /// <param name="birthDate">生日</param>
        /// <returns></returns>
        public static int CalculateAge(string birthDay)
        {
            DateTime birthDate=DateTime.Parse(birthDay);
            DateTime nowDateTime=DateTime.Now;
            int age = nowDateTime.Year - birthDate.Year;
            //再考虑月、天的因素
            if (nowDateTime.Month < birthDate.Month || (nowDateTime.Month == birthDate.Month && nowDateTime.Day < birthDate.Day))
            { 
                age--; 
            }
            return age;
        }

        /// <summary>
        /// 定义 生日年龄性别 实体
        /// </summary>
        public class BirthdayAgeSex
        {
            public string Birthday { get; set; }
            public int Age { get; set; }
            public string Sex { get; set; }
        }
    }
}

复制代码

(ps:多年前写的了,今天看了下,确实很水啊。。。。)

C#识别身份证号码(经典版)

  1. using System;

  2. using System.Collections.Generic;

  3. using System.ComponentModel;

  4. using System.Data;

  5. using System.Drawing;

  6. using System.Linq;

  7. using System.Text;

  8. using System.Windows.Forms;

  9. using System.Data.OleDb;

  10. namespace ValidateIDcard

  11. {

  12. public partial class Form1 : Form

  13. {

  14. public Form1()

  15. {

  16. InitializeComponent();

  17. }

  18.  
  19. string strg;//数据库路径

  20. OleDbConnection conn;//数据连接对象

  21. OleDbCommand cmd;//OleDbCommand对象

  22. OleDbDataReader sdr;//OleDbDataReader对象

  23.  
  24. private bool CheckCard(string cardId)//创建一个CheckCard方法用于检查身份证号码是否合法

  25. {

  26. if (cardId.Length == 18) //如果身份证号为18位

  27. {

  28. return CheckCard18(cardId);//调用CheckCard18方法验证

  29. }

  30. else if (cardId.Length == 15) //如果身份证号为15位

  31. {

  32. return CheckCard15(cardId);//调用CheckCard15方法验证

  33. }

  34. else

  35. {

  36. return false;

  37. }

  38. }

  39.  
  40. private bool CheckCard18(string CardId)//CheckCard18方法用于检查18位身份证号码的合法性

  41. {

  42. long n = 0;

  43. bool flag = false;

  44. if (long.TryParse(CardId.Remove(17), out n) == false || n < Math.Pow(10, 16) || long.TryParse(CardId.Replace('x', '0').Replace('X', '0'), out n) == false)

  45. return false;//数字验证

  46. string[] Myaddress =new string[]{ "11","22","35","44","53","12",

  47. "23","36","45","54","13","31","37","46","61","14","32","41",

  48. "50","62","15","33","42","51","63","21","34","43","52","64",

  49. "65","71","81","82","91"};

  50. for (int kk = 0; kk < Myaddress.Length;kk++ )

  51. {

  52. if (Myaddress[kk].ToString() == CardId.Remove(2))

  53. {

  54. flag = true;

  55. }

  56. }

  57. if (flag)

  58. {

  59. return flag;

  60. }

  61. string Mybirth = CardId.Substring(6, 8).Insert(6, "-").Insert(4, "-");

  62. DateTime Mytime = new DateTime();

  63. if (DateTime.TryParse(Mybirth, out Mytime) == false)

  64. return false;//生日验证

  65. string[] MyVarifyCode = ("1,0,x,9,8,7,6,5,4,3,2").Split(',');

  66. string[] wi = ("7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2").Split(',');

  67. char[] ai = CardId.Remove(17).ToCharArray();

  68. int sum = 0;

  69. for (int i = 0; i < 17; i++)

  70. sum += int.Parse(wi[i]) * int.Parse(ai[i].ToString());

  71. int y = -1;

  72. Math.DivRem(sum, 11, out y);

  73. if (MyVarifyCode[y] != CardId.Substring(17, 1).ToLower())

  74. {

  75. return false;//校验码验证

  76. }

  77. return true;//符合GB11643-1999标准

  78. }

  79.  
  80. private bool CheckCard15(string CardId)

  81. {

  82. long n = 0;

  83. bool flag = false;

  84. if (long.TryParse(CardId, out n) == false || n < Math.Pow(10, 14))

  85. return false;//数字验证

  86. string[] Myaddress = new string[]{ "11","22","35","44","53","12",

  87. "23","36","45","54","13","31","37","46","61","14","32","41",

  88. "50","62","15","33","42","51","63","21","34","43","52","64",

  89. "65","71","81","82","91"};

  90. for (int kk = 0; kk < Myaddress.Length; kk++)

  91. {

  92. if (Myaddress[kk].ToString() == CardId.Remove(2))

  93. {

  94. flag = true;

  95. }

  96. }

  97. if (flag)

  98. {

  99. return flag;

  100. }

  101. string Mybirth = CardId.Substring(6, 6).Insert(4, "-").Insert(2, "-");

  102. DateTime Mytime = new DateTime();

  103. if (DateTime.TryParse(Mybirth, out Mytime) == false)

  104. {

  105. return false;//生日验证

  106. }

  107. return true;//符合15位身份证标准

  108. }

  109.  
  110. private void button1_Click(object sender, EventArgs e)

  111. {

  112. if (txtCardID.Text == "")//如果没有输入身份证号码

  113. {

  114. return; //不执行操作

  115. }

  116. if (CheckCard(txtCardID.Text.Trim()))//如果通过CheckCard方法验证成功

  117. {

  118. this.Height = 237; //设置窗体高度

  119. string card=txtCardID.Text.Trim();//获取输入的身份证号码

  120. if (card.Length == 15) //如果输入的是15位的身份证号码,需要将其转换成18位

  121. {

  122. int[] w = new int[] { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 };

  123. char[] a = new char[] { '1', '0', 'x', '9', '8', '7', '6', '5', '4', '3', '2' };

  124. string newID = "";

  125. int s = 0;

  126. newID =this.txtCardID.Text.Trim().Insert(6, "19");

  127. for (int i = 0; i < 17; i++)

  128. {

  129. int k = Convert.ToInt32(newID[i]) * w[i];

  130. s = s + k;

  131. }

  132. int h = 0;

  133. Math.DivRem(s, 11, out h);

  134. newID = newID + a[h];

  135. card = newID; //最后将转换成18位的身份证号码赋值给card

  136. }

  137. int addnum =Convert.ToInt32(card.Remove(6));//获取身份证号码中的地址码

  138. //连接数据库

  139. conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data source=" + strg);

  140. conn.Open();//打开数据库

  141. //查找数据库中是否存在输入的身份证号码中的地址码

  142. cmd = new OleDbCommand("select count(*) from address where AddNum="+addnum, conn);

  143. int KK = Convert.ToInt32(cmd.ExecuteScalar());

  144. if (KK > 0)//如果存在

  145. {

  146. //检索数据库

  147. cmd = new OleDbCommand("select * from address where AddNum=" + addnum, conn);

  148. //实例化OleDbDataReader对象

  149. sdr = cmd.ExecuteReader();

  150. sdr.Read();//读取该对象

  151. string address = sdr["AddName"].ToString();//获取地址码对应的归属地

  152. string birthday = card.Substring(6, 8);//从身份证号码中截取出公民的生日

  153. string byear = birthday.Substring(0,4);//获取出生年份

  154. string bmonth = birthday.Substring(4,2);//获取出生月份

  155. if (bmonth.Substring(0, 1) == "0")//如果月份是以0开头

  156. {

  157. bmonth = bmonth.Substring(1,1);//去掉0

  158. }

  159. string bday = birthday.Substring(6,2);//获取出生“日”

  160. if (bday.Substring(0, 1) == "0")//如果“日”以0开头

  161. {

  162. bday = bday.Substring(1, 1);//去掉0

  163. }

  164. string sex = "";//性别

  165. if (txtCardID.Text.Trim().Length == 15)//如果输入的身份证号码是15位

  166. {

  167. int PP=Convert.ToInt32(txtCardID.Text.Trim().Substring(14,1))%2;//判断最后一位是奇数还是偶数

  168. if (PP == 0)//如果是偶数

  169. {

  170. sex = "女";//说明身份证号码的持有者是女性

  171. }

  172. else

  173. {

  174. sex = "男";//如果是奇数则身份证号码的持有者是男性

  175. }

  176. }

  177. if (txtCardID.Text.Trim().Length == 18)//如果输入的身份证号码是18位

  178. {

  179. int PP = Convert.ToInt32(txtCardID.Text.Trim().Substring(16, 1)) % 2;//判断倒数第二位是奇数还是偶数

  180. if (PP == 0)//如果是偶数

  181. {

  182. sex = "女";//说明身份证号码的持有者是女性

  183. }

  184. else

  185. {

  186. sex = "男";//如果是奇数则身份证号码的持有者是男性

  187. }

  188. }

  189. sdr.Close();//关闭OleDbDataReader连接

  190. conn.Close();//关闭数据库连接

  191. lblAddress.Text = address;//显示身份证持有者的归属地

  192. lblbirthday.Text = byear + "年" + bmonth + "月" + bday + "日";//显示身份证持有者的生日

  193. lblsex.Text = sex;//显示身份证持有者的性别

  194. lblresult.Text = "合法的公民身份证号!";//显示验证结果

  195. }

  196. else

  197. {

  198. MessageBox.Show("公民身份证号输入有误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

  199. }

  200. }

  201. else

  202. {

  203. MessageBox.Show("非法公民身份证号!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

  204. }

  205. }

  206.  
  207. private void button2_Click(object sender, EventArgs e)

  208. {

  209. txtCardID.Text = "";//清空输入框

  210. this.Height = 78; //设置窗体高度位78

  211. }

  212.  
  213. private void Form1_Load(object sender, EventArgs e)

  214. {

  215. this.Height = 78;//设置窗体高度

  216. //获取数据库路径

  217. strg = Application.StartupPath.ToString();

  218. strg += @"\db.accdb";

  219. }

  220. }

  221. }

  222. *****************************************************************************

public class PackIden
    {
        /// <summary>
        /// 根据身份证获取生日
        /// </summary>
        /// <param name="cardid">身份证</param>
        /// <param name="res">是否有格式(true1990-01-01,false19900101)</param>
        /// <returns></returns>
        public static string GetBirthdayByIdentityCardId(string cardid, bool res)
        {
            string birthday = string.Empty;
            System.Text.RegularExpressions.Regex regex = null;

            if (cardid.Length == 18)
            {
                regex = new Regex(@"^\d{17}(\d|x)$");
                if (regex.IsMatch(cardid))
                {
                    if (res)
                        birthday = cardid.Substring(6, 8).Insert(4, "-").Insert(7, "-");
                    else
                        birthday = cardid.Substring(6, 8);
                }
                else
                {
                    birthday = "invalid cardid";
                }
            }
            else if (cardid.Length == 15)
            {
                regex = new Regex(@"^\d{15}");
                if (regex.IsMatch(cardid))
                {
                    if (res)
                        birthday = cardid.Substring(6, 6).Insert(2, "-").Insert(5, "-");
                    else
                        birthday = cardid.Substring(6, 6);
                }
                else
                {
                    birthday = "invalid cardid";
                }
            }
            else
            {
                birthday = "invalid cardid";
            }

            return birthday;
        }


        /// <summary>
        /// 根据身份证获取身份证信息
        /// 18位身份证
        /// 0地区代码(1~6位,其中1、2位数为各省级政府的代码,3、4位数为地、市级政府的代码,5、6位数为县、区级政府代码)
        /// 1出生年月日(7~14位)
        /// 2顺序号(15~17位单数为男性分配码,双数为女性分配码)
        /// 3性别
        /// 
        /// 15位身份证
        /// 0地区代码 
        /// 1出生年份(7~8位年,9~10位为出生月份,11~12位为出生日期 
        /// 2顺序号(13~15位),并能够判断性别,奇数为男,偶数为女
        /// 3性别
        /// </summary>
        /// <param name="cardId"></param>
        /// <returns></returns>
        public static string[] GetCardIdInfo(string cardId)
        {
            string[] info = new string[4];
            System.Text.RegularExpressions.Regex regex = null;
            if (cardId.Length == 18)
            {
                regex = new Regex(@"^\d{17}(\d|x)$");
                if (regex.IsMatch(cardId))
                {
                    info.SetValue(cardId.Substring(0, 6), 0);
                    info.SetValue(cardId.Substring(6, 8), 1);
                    info.SetValue(cardId.Substring(14, 3), 2);
                    info.SetValue(Convert.ToInt32(info[2]) % 2 != 0 ? "男" : "女", 3);
                }
            }
            else if (cardId.Length == 15)
            {
                regex = new Regex(@"^\d{15}");
                if (regex.IsMatch(cardId))
                {
                    info.SetValue(cardId.Substring(0, 6), 0);
                    info.SetValue(cardId.Substring(6, 6), 1);
                    info.SetValue(cardId.Substring(12, 3), 2);
                    info.SetValue(Convert.ToInt32(info[2]) % 2 != 0 ? "男" : "女", 3);
                }
            }

            return info;

        }

    }

复制代码

18位的身份证,前面六位代表了你户籍所在地,第七位到第十四位代表了你的出生年月,第十五位到第十七为代表了你的性别(偶数为女,奇数为男),根据这一信息,我在系统开发的录入员工的身份证后控件焦点转移时根据身份证号码获得生日和性别。

  用C#写的代码如下:

        /// <summary>
        /// 在控件验证 textBox_IdentityCard 的 Validated事件中定义身份证号码的合法性并根据身份证号码得到生日和性别  
        /// </summary>
        private void textBox_IdentityCard_Validated(object sender, EventArgs e)
        {
            try
            {
                //获取得到输入的身份证号码
                string identityCard = textBox_IdentityCard.Text.Trim();

                if (string.IsNullOrEmpty(identityCard))
                {
                    //身份证号码不能为空,如果为空返回
                    MessageBox.Show("身份证号码不能为空!");
                    if (textBox_IdentityCard.CanFocus)
                    {
                        textBox_IdentityCard.Focus();//设置当前输入焦点为textBox_IdentityCard
                    }
                    return;
                }
                else
                {
                    //身份证号码只能为15位或18位其它不合法
                    if (identityCard.Length != 15 && identityCard.Length != 18)
                    {
                        MessageBox.Show("身份证号码为15位或18位,请检查!");
                        if (textBox_IdentityCard.CanFocus)
                        {
                            textBox_IdentityCard.Focus();
                        }
                        return;
                    }
                }

                string birthday = "";
                string sex = "";

                //处理18位的身份证号码从号码中得到生日和性别代码
                if (identityCard.Length == 18)
                {
                    birthday = identityCard.Substring(6, 4) + "-" + identityCard.Substring(10, 2) + "-" + identityCard.Substring(12, 2);
                    sex = identityCard.Substring(14, 3);
                }
                //处理15位的身份证号码从号码中得到生日和性别代码
                if (identityCard.Length == 15)
                {
                    birthday = "19" + identityCard.Substring(6, 2) + "-" + identityCard.Substring(8, 2) + "-" + identityCard.Substring(10, 2);
                    sex = identityCard.Substring(12, 3);
                }
                textBox_Birthday.Text = birthday;
                //性别代码为偶数是女性奇数为男性
                if (int.Parse(sex) % 2 == 0)
                {
                    this.comboBox_Sex.Text = "女";
                }
                else
                {
                    this.comboBox_Sex.Text = "男";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("身份证号码输入有误");
                if (textBox_IdentityCard.CanFocus)
                {
                    textBox_IdentityCard.Focus();
                }
                return;
            }
        }

猜你喜欢

转载自blog.csdn.net/qmdweb/article/details/81297831