英文:
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 '001205'
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 than23
so we can prepend20
so the full year is2005
. - An input year of
27
is greater than23
so we can prepend19
so the full year is1927
.
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 < 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'));
<!-- 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 = "19" + 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 <= currentYear? '20' : '19') + year}`;
}
['931205','150124'].forEach( id =>
console.log(`${id} => ${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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论