Get exact age from datepicker?

I am trying to disable a form submit button if the user is under 18. I found the following code through the forum and it works for the year but it doesn’t factor in the day or month in the date of birth. So when the user selects any month or day in a year, it returns the age to be the same.

$w.onReady(function () {
    $w("#datePicker1").onChange((event) => {
        let newValue = event.target.value; // "new value"
        let age = getAge(newValue);
          console.log('age: ', age);
        if (age >= 18) {
              $w('#button1').enable();
          } else {
              $w('#button1').disable();
          }
    });
});

function getAge(dateString) {
    var today = new Date();
    var birthDate = new Date(dateString);
    var age = today.getFullYear() - birthDate.getFullYear();
    var m = today.getMonth() - birthDate.getMonth();
    if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
         age--;
     }
    return age;
}

I was thinking I could add a variable for day like this:

var d = today.getDay() - birthDate.getDay();

but I have no idea how I would get the month and day to be calculated in the equation…

What is it exactly that you are trying to accomplish? I have a test site that uses the same code and it returns my age in years (a lot of them) just fine.

Are you trying to get the age in months? days? hours?

Thank you for responding, it turns out I had been staring at the computer for far too long and could no longer realise the math was correct, haha! All works fine, sorry for the false alarm!

Whilst I have you here, I don’t suppose you could help me with how to change the matching date to a database date field instead of ‘today’? (so they would need to be 18 on ‘x’ date)

Update: I’ve added the “let itemObj” lines to the following code which is returning the correct date from the dataset. So now I just need to figure out how to change the " var today = new Date (); fr " from the code above to = programDate

export function programSelectDropdown_change(event) {

 if($w('#programSelectDropdown').value==='Soccer') {
        $w('#soccerRegistrationBox').expand();
    } else {
        $w('#soccerRegistrationBox').collapse();
    }

 let itemObj = $w("#programsDataset").getCurrentItem();
 let programDate = itemObj.coedSpringStart
        console.log("program date:",programDate)

}

If you’re looking for their exact age, to day, month, year you’ll have to utilise the milliseconds and convert. it’s not complex it’s just a bit more code, I’ve Achieved it on my site I will past code here once at laptop.

@lisamthorpe OK, you need to adjust your function to something like this:

function getAge(dateString, programDate) {
    var birthDate = new Date(dateString);
    var age = programDate.getFullYear() - birthDate.getFullYear();
    var m = programDate.getMonth() - birthDate.getMonth();
    if (m < 0 || (m === 0  &&  programDate.getDate() < birthDate.getDate())) {
         age--;
     }
    return age;
}

Disclaimer: I haven’t test this, but that’s the general idea.

Hey @lisamthorpe

You also need to check the month and day, not just the year, @yisrael-wix already gave you the answer, but I’m going to explain it for you and for others.

const date = $w('#datePicker').value; // Get the value from the date picker

function getAge(date) {
    // A variable to see if the person age is above 18;
    let legalAge = false;

    // Variables for the age
    let age = { year: 0, month: 0, day: 0 };

    // Get today's date.
    const today = new Date();

    // Get the age of based on the birthday
    age.year = today.getFullYear() - date.getFullYear(); // Get the year difference
    age.month = today.getMonth() - date.getMonth(); // Get the month difference
    age.day = today.getDate() - date.getDate(); // Get the day difference
    
    if (age.month < 0) {
        /* If the current month is past the birthday month, then the person
           is one year younger, and we need decrease the year age.
        */
        age.year--;
    } else if (age.month === 0 && age.day < 0) {
        /* If the current month is the same as the given month, and the current
           day is before the person birthday day, and we need decrease the year age.
        */
        age.year--;
    }

    // Check if the year difference is in the legal age (greater or equal to 18)
    if (age.year >= 18) {    
        // Now check if the current month is after the birthday month or the same
        if (age.month >= 0) {
            // Now check if the current day is the same or after the birthday day
            if (age.day >= 0) {
                // The person is 18 years old or more.
                legalAge = true;
            }
        }
    }
    
    /*  prepare the data to return it - you don't need this part
        This part will return the age like this (19 Years, 5 Months and 7 Days)       
    */    
    let ageText = `${age.year} Years`;
    if (age.month > 0) {
        if (age.month === 1) {
            ageText = `${ageText}, 1 Month`;
        } else if (age.month > 1) {
            ageText = `${ageText}, ${age.month} Months`;
        }
    }
    
    if (age.day > 0) {
        if (age.day === 1) {
            ageText = `${ageText} and 1 Day`;
        } else if (age.day > 1) {
            ageText = `${ageText} and ${age.day} Days`;
        }
    }
    
    // Return the final results.
    return {
        legalAge: legalAge,
        age: {
            numeric: age.year,
            text: ageText
        }
    }
}

/*  Calling the function getAge() with the date picker as a parameter
    will return the following result - It'll differ by the date you select
*/    

/*
    Object {
        legalAge: true,
        age: {
            numeric: 26,
            text: "26 Years, 2 Months and 4 Days"
        }
    }
*/

Hope this helps~!
Ahmad

@yisrael-wix Thank you, I have just tested and the following error is returned: Cannot read property ‘getFullYear’ of undefined ( in var age = programDate.getFullYear() )

I’m guessing it’s because programDate has been defined in a separate enclosed function?

So this is now an overview of the relevant snippets of code…

$w.onReady(function () {
    $w("#datePicker1").onChange((event) => {
        let newValue = event.target.value; // "new value"
        let age = getAge(newValue);
          console.log('age: ', age);
        if (age >= 18) {
              $w('#button1').enable();
          } else {
              $w('#button1').disable();
          }
    });
});


export function programSelectDropdown_change(event) {

 if($w('#programSelectDropdown').value==='Soccer') {
        $w('#soccerRegistrationBox').expand();
    } else {
        $w('#soccerRegistrationBox').collapse();
    }

 let itemObj = $w("#programsDataset").getCurrentItem();
 let programDate = itemObj.coedSpringStart
        console.log("program date:",programDate)

}


function getAge(dateString, programDate) {
 var birthDate = new Date(dateString);
 var age = programDate.getFullYear() - birthDate.getFullYear();
 var m = programDate.getMonth() - birthDate.getMonth();
 if (m < 0 || (m === 0  &&  programDate.getDate() < birthDate.getDate())) {
         age--;
     }
 return age;
}

@ahmadnasriya Thank you for explaining that for me :slight_smile: I think the original function ended up working correctly after all. I don’t suppose you have any advice on what might be happening in my last reply to Yisrael?

@lisamthorpe declared " programDate " as a parameter as the current date, just for reference. The programDate is current date, and you can get it like this:

let programDate = new Date();