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\$ 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
    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\$ 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
    Jan 29, 2016 at 16:30
  • \$\begingroup\$ why shouldn't it? Date should be available in all browsers. \$\endgroup\$
    – lex82
    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
    Jan 29, 2016 at 16:36
  • \$\begingroup\$ Found out! The new Date(year, month, date) is EcmaScript standard! Awesome, thank you! \$\endgroup\$
    – falsarella
    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
    Jan 29, 2016 at 17:39

Your Answer

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

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