Calculate age with month inclusive

I have a custom formatter for client-side that takes 2 parameters, the DoB and the date to compare it to (often the current date from a date & time component):

dmx.Formatter('string', 'getage', function getAge(dateString, toDate) {
    var now = new Date(toDate);
    var yearNow = now.getYear();
    var monthNow = now.getMonth();
    var dateNow = now.getDate();
    var dob = new Date(dateString);
    var yearDob = dob.getYear();
    var monthDob = dob.getMonth();
    var dateDob = dob.getDate();
    var age = {};
    var ageString = "";
    var yearString = "";
    var monthString = "";
    var dayString = "";

    yearAge = yearNow - yearDob;

    if (monthNow >= monthDob)
        var monthAge = monthNow - monthDob;
    else {
        yearAge--;
        var monthAge = 12 + monthNow - monthDob;
    }

    if (dateNow >= dateDob)
        var dateAge = dateNow - dateDob;
    else {
        monthAge--;
        var dateAge = 31 + dateNow - dateDob;

        if (monthAge < 0) {
            monthAge = 11;
            yearAge--;
        }
    }

    age = {
        years: yearAge,
        months: monthAge,
        days: dateAge
    };

    if (age.years > 1) yearString = " years";
    else yearString = " year";
    if (age.months > 1) monthString = " months";
    else monthString = " month";
    if (age.days > 1) dayString = " days";
    else dayString = " day";


    if ((age.years > 0) && (age.months > 0) && (age.days > 0))
        ageString = age.years + yearString + ", " + age.months + monthString + " and " + age.days + dayString;
    else if ((age.years == 0) && (age.months == 0) && (age.days > 0))
        ageString = "Only " + age.days + dayString;
    else if ((age.years > 0) && (age.months == 0) && (age.days == 0))
        ageString = age.years + yearString;
    else if ((age.years > 0) && (age.months > 0) && (age.days == 0))
        ageString = age.years + yearString + " and " + age.months + monthString;
    else if ((age.years == 0) && (age.months > 0) && (age.days > 0))
        ageString = age.months + monthString + " and " + age.days + dayString;
    else if ((age.years > 0) && (age.months == 0) && (age.days > 0))
        ageString = age.years + yearString + " and " + age.days + dayString;
    else if ((age.years == 0) && (age.months > 0) && (age.days == 0))
        ageString = age.months + monthString;
    else ageString = "Could not calculate age!";

    age.yearmonthdays = ageString;

    if ((age.years > 0) && (age.months > 0))
        ageString = age.years + yearString + " " + age.months + monthString;
    else if ((age.years == 0) && (age.months == 0) && (age.days > 0))
        ageString = age.days + dayString;
    else if ((age.years > 0) && (age.months > 0) && (age.days == 0))
        ageString = age.years + yearString + " and " + age.months + monthString;
    else if ((age.years == 0) && (age.months > 0))
        ageString = age.months + monthString;
    else if ((age.years > 0) && (age.months == 0))
        ageString = age.years + yearString;
    else ageString = "Could not calculate age!";

    age.yearmonths = ageString;

    return age;
});

It returns an object of different values for the age depending on what you want (in this case, it sounds like the yearmonthdays value is best:
image

Add it to your page using the following instructions (for client-side):

and then you can use it:

{{applicant_data_detail.data.a01_DoB.getage(currentDateAndTime.datetime).yearmonthdays}}

Just be careful if you use the date and time component. If it is set to interval seconds, you may find things that are bound to it, that only use the date, updated unnecessarily every second which can slow your page down (if you have a complex page). You could add another one set to interval in minutes or hours.

*updated to remove comma before 'and # days'

2 Likes