从南非身份证号生成出生日期

huangapple go评论73阅读模式
英文:

Generate date of birth from South African ID number

问题

var currDate = new Date("20" + saIDNumber.substring(0, 2),
                            saIDNumber.substring(2, 4) - 1,
                            saIDNumber.substring(4, 6)); 
var id_date  = currDate.getDate(); 
var id_month = currDate.getMonth() + 1; 
var id_year  = currDate.getFullYear();
英文:

How can I generate the date of birth from South African ID number?

The first 6 digits of the ID number represent their date of birth in the format YYMMDD.

From the ID number inputted by the user, I want to extract the first 6 characters and use this to fill in the date of birth input Date in the format dd/mm/yyyy

This is my code to get first 6 digits as a valid date:

var currDate = new Date(saIDNumber.substring(0, 2),
                        saIDNumber.substring(2, 4) - 1,
                        saIDNumber.substring(4, 6)); 
var id_date  = currDate.getDate(); 
var id_month = currDate.getMonth(); 
var id_year  = currDate.getFullYear();

The code doesn't generate the date of birth automatically but it doesn't show any errors either.

答案1

得分: 2

Here is the translated content:

"对你的代码稍作修改,因为在阅读评论后发现了一些问题!总的来说,你的代码是有效的,但是在1999年之后,日期会出现问题,因为那时两位数的年份可能以前导零开头,而数字中不允许出现前导零。例如,在控制台运行 console.log(001234) 将产生 668,因为它似乎会尝试将这个数字转换为八进制数,详情请看这里

因此,你必须始终将“numbers”输入保存为数字字符串,以确保数据准确性。这意味着你必须始终将这些数字保存为字符串,并将它们传递为字符串。

另一个问题是,1999年之后的日期将假定为 '19' 前缀。因此,'001205' 这样的数字将假定 '00' 意味着 '1900' 而不是 '2000'。正如上面的评论中指出的,一个人年龄超过100岁的几率只有0.025%,而且在这个国家,这么老的人可能根本没有颁发身份证号码,因此可以安全地假设他们是在本世纪出生的。

我认为解决这个问题的好方法是将两位数的输入年份与当前年份的最后两位数字进行比较。我写这篇文章时是 '2023',所以变成 '23'。以下是一些示例:

  • 输入年份 '05' 小于 '23',所以我们可以添加 '20',使完整年份为 '2005'。
  • 输入年份 '27' 大于 '23',所以我们可以添加 '19',使完整年份为 '1927'。

这是我的建议,考虑到所有这些因素。我还删除了对 'Date' 对象的需求。这意味着现在我们不需要从月份中减去1。我们只需从字符串中获取数字,然后将其解析为实际数字。

function parseIdNumber(numStr){
  //如果输入年份的最后两位数字小于当前年份的最后两位数字,则假定他们在2000年之后出生
  var currentYearTwoDigits = parseInt(new Date().getFullYear().toString().substring(2,4), 10);
  var inputYear = parseInt(numStr.substring(0, 2), 10);
  var bestGuessYear = (inputYear < currentYearTwoDigits ? '20' : '19') + inputYear;

 return {
  day: parseInt(numStr.substring(4, 6), 10),
  month: parseInt(numStr.substring(2, 4), 10),
  year: parseInt(bestGuessYear, 10)
 }
}

console.log(parseIdNumber('541213'));
console.log(parseIdNumber('841003'));
console.log(parseIdNumber('930214'));
console.log(parseIdNumber('991205'));
console.log(parseIdNumber('000101'));
console.log(parseIdNumber('071205'));
console.log(parseIdNumber('220824'));

Hope this helps!

英文:

Rewriting my answer a bit because I found some issues after reading the comments! Generally your code works, but you WILL have issues with dates after 1999 because a two-digit year after that can begin with a leading zero, which is not allowed in a number. For example in the console running console.log(001234) will produce 668 since it apparently will try to convert this number into octal!

So, you absolutely must have the "numbers" input as strings of numbers to ensure your data is accurate. This means you must always save these number as strings, and pass them around as strings.

With that covered the other issue is that dates after 1999 will assume a '19' prefix. So a number of &#39;001205&#39; will assume the year meant by 00 is 1900 and not 2000. As it was pointed out above in a comment there is a 0.025% chance for a person to be over 100 years old, and that a person this old in this country may not have even been issued a number, this seems like it's safe to assume they were worn in this century.

I think a good way to address this is to compare the two digit input year against the last two digits of the current year. As I write this is is 2023, so that becomes 23. Here are some examples

  • An input year of 05 is less than 23 so we can prepend 20 so the full year is 2005.
  • An input year of 27 is greater than 23 so we can prepend 19 so the full year is 1927.

Here is my recommendation that takes all of this into account. I also removed the need for a Date object. This means we don't need to subtract 1 from the month now either. We can just get the numbers from the string and then parse them into real numbers.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function parseIdNumber(numStr){
  //if the last 2 digits of the input year are less than the last 2 of the current year
  //assume they were born after the year 2000
  var currentYearTwoDigits = parseInt(new Date().getFullYear().toString().substring(2,4), 10);
  var inputYear = parseInt(numStr.substring(0, 2), 10);
  var bestGuessYear = (inputYear &lt; currentYearTwoDigits ? &#39;20&#39; : &#39;19&#39;) + inputYear;

 return {
  day: parseInt(numStr.substring(4, 6), 10),
  month: parseInt(numStr.substring(2, 4), 10),
  year: parseInt(bestGuessYear, 10)
 }
}

console.log(parseIdNumber(&#39;541213&#39;));
console.log(parseIdNumber(&#39;841003&#39;));
console.log(parseIdNumber(&#39;930214&#39;));
console.log(parseIdNumber(&#39;991205&#39;));
console.log(parseIdNumber(&#39;000101&#39;));
console.log(parseIdNumber(&#39;071205&#39;));
console.log(parseIdNumber(&#39;220824&#39;));

<!-- end snippet -->

答案2

得分: 1

以下是您要翻译的内容:

不需要使用Date对象,与OP代码相同的结果如下所示:

var id_date = saIDNumber.substring(4, 6);
var id_month = saIDNumber.substring(2, 4);
var id_year = "19" + saIDNumber.substring(0, 2);

Date构造函数 将年份值0到99视为1900 + year(参见步骤5.j.ii)。

存在一个问题,自1999年以来出生的任何人(即年份值00到23)将被视为1900年至1923年。您可能会假设任何ID年份在当前两位数年份之前的必须在21世纪,但会有一些百岁老人再次成为儿童。 从南非身份证号生成出生日期

所以:

function getIDDate(saIDNumber) {
    let currentYear = new Date().getFullYear() % 100;
    let [year, month, day] = saIDNumber.match(/\d\d/g);
    return `${day}/${month}/${(year <= currentYear ? '20' : '19') + year}`;
}

['931205', '150124'].forEach(id =>
    console.log(`${id} => ${getIDDate(id)}`)
);

这不会验证值,它们可能不代表有效日期。

PS。

new Date().getFullYear() % 100 可以替换为 new Date().getYear(),但我认为前者更清晰,以获取适当的年份值。

英文:

There is no need to use a Date object, an identical result to the OP code is given by:

var id_date  = saIDNumber.substring(4, 6);
var id_month = saIDNumber.substring(2, 4); 
var id_year  = &quot;19&quot; + saIDNumber.substring(0, 2);

The Date constructor treats year values 0 to 99 as 1900 + year (see step 5.j.ii).

There is an issue that anyone born since 1999 (i.e. year value 00 to 23) will be treated as 1900 to 1923. You might assume that any ID year that is prior to the current two digit year must be in the 21st century, but there will be centenarians who will be children again. 从南非身份证号生成出生日期

So:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function getIDDate(saIDNumber) {
    let currentYear = new Date().getFullYear() % 100;
    let [year, month, day]  = saIDNumber.match(/\d\d/g);
    return `${day}/${month}/${(year &lt;= currentYear? &#39;20&#39; : &#39;19&#39;) + year}`;
}

[&#39;931205&#39;,&#39;150124&#39;].forEach( id =&gt;
  console.log(`${id} =&gt; ${getIDDate(id)}`)
);

<!-- end snippet -->

This doesn't validate the values, they may not represent a valid date.

PS.

new Date().getFullYear() % 100 could be new Date().getYear() but I think the former is clearer in getting an appropriate year value.

huangapple
  • 本文由 发表于 2023年5月13日 11:57:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76241004.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定