8
\$\begingroup\$

Considering that:

  • the passed parameters are all numbers
  • the passed date is a valid date

It should return:

  • true if the date is 18 or more years old
  • false otherwise

function isDate18orMoreYearsOld(day, month, year) {
    var maxBirthDate = new Date();
    maxBirthDate = new Date(maxBirthDate.setYear(maxBirthDate.getYear() - 18));
    var maxYear = maxBirthDate.getYear();
    var maxMonthOnMaxYear = maxBirthDate.getMonth() + 1;
    var maxDayOnMaxMonthOnMaxYear = maxBirthDate.getDate();
    if (year > maxYear) {
        return true;
    }
    if (year == maxYear) {
        if (month > maxMonthOnMaxYear) {
            return true;
        }
        if (month == maxMonthOnMaxYear) {
            if (day >= maxDayOnMaxMonthOnMaxYear) {
                return true;
            }
        }
    }
    return false;
}

Despite I don't want to lose maintainability and readability, I feel it could possibly have a lesser number of conditional statements.

Is there any improvement you suggest?

Also, if you spot any cases that the function fails it's very welcome.

\$\endgroup\$
3
  • \$\begingroup\$ Can you be more specific about your performance and portability concerns? \$\endgroup\$ Commented Jan 29, 2016 at 17:56
  • \$\begingroup\$ @200_success Nice point! I actually tagged it optimization and cross-browser, but it was weirdly automatically retagged to performance and portability, which are very distinct terms IMO. I was making a note here to ask it on meta later on. (Despite I'm unsure about optimization usage, my intent was to tag with something like shortening, or refactoring, but optimization was the closest term I found - if you have any suggestion I'd appreciate your guidance!). \$\endgroup\$
    – falsarella
    Commented Jan 29, 2016 at 18:06
  • 1
    \$\begingroup\$ If you're just looking for a general shortening, don't bother tagging it as such — it's implied in every question. \$\endgroup\$ Commented Jan 29, 2016 at 18:40

1 Answer 1

16
\$\begingroup\$

What about this:

function isDate18orMoreYearsOld(day, month, year) {
    return new Date(year+18, month-1, day) <= new Date();
}

The month - 1 is required because JS months start at 0.

\$\endgroup\$
6
  • \$\begingroup\$ Seems great, but, is it cross-browser? \$\endgroup\$
    – falsarella
    Commented Jan 29, 2016 at 16:30
  • \$\begingroup\$ why shouldn't it? Date should be available in all browsers. \$\endgroup\$
    – lex82
    Commented Jan 29, 2016 at 16:32
  • \$\begingroup\$ Sorry, I meant the constructor. I know some Date constructors aren't fully supported on all browsers. I'm just not sure which one. \$\endgroup\$
    – falsarella
    Commented Jan 29, 2016 at 16:36
  • \$\begingroup\$ Found out! The new Date(year, month, date) is EcmaScript standard! Awesome, thank you! \$\endgroup\$
    – falsarella
    Commented Jan 29, 2016 at 16:54
  • \$\begingroup\$ Very clever, btw: it passed all corner cases I've tested, including some leap year validations. \$\endgroup\$
    – falsarella
    Commented Jan 29, 2016 at 17:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.