skip to Main Content

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.

2

Answers


  1. 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 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.

    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(Date.now()).getFullYear().toString().substring(2,4), 10);
      var inputYear = numStr.substring(0, 2);
      var bestGuessYear = (inputYear < currentYearTwoDigits ? '20' : '19') + inputYear;
    
     return {
      date: 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'));
    Login or Signup to reply.
  2. 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:

    function getIDDate(saIDNumber) {
        let currentYear = new Date().getFullYear() % 100;
        let [year, month, day]  = saIDNumber.match(/dd/g);
        return `${day}/${month}/${(year <= currentYear? '20' : '19') + year}`;
    }
    
    ['931205','150124'].forEach( id =>
      console.log(`${id} => ${getIDDate(id)}`)
    );

    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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search