Using ISO strings for DateTime minDate can show year < minDate

Using ISO strings for DateTime minDate can show year < minDate

Loren MaxwellLoren Maxwell Posts: 443Questions: 106Answers: 10
edited June 13 in DateTime

I notice an issue with the DateTime picker on this page: https://editor.datatables.net/examples/dates/options-min-max.html

Note that 2010 is present in the select for the year even though minDate is 2011-01-01 so years prior to 2011 shouldn't show.

For anyone not familiar with this phenomenon, this is caused by minDate and maxDate being passed as strings in ISO format (YYYY-MM-DD) to their new Date() objects,. The Date object will convert those strings to local time and give this unexpected result.

For the uninitiated this can be particularly frustrating:

const d = new Date('2011-01-01');  // ISO format of `YYYY-MM-DD`

console.log(d.getFullYear()); // = 2010???

But here's a way to see what's actually happening:

const d = new Date('2011-01-01');  // ISO format of `YYYY-MM-DD`

console.log(d.toISOString()); // "2011-01-01T00:00:00.000Z"

console.log(d.toString()); // Local "Fri Dec 31 2010 19:00:00 GMT-0500 (Eastern Standard Time)"

console.log(d.getFullYear()); // 2010

To avoid this, construct the date in local time:

const d = new Date(2011, 0, 1); // Month is zero-indexed (0 = January)

console.log(d.toString()); // "Sat Jan 01 2011 00:00:00 GMT-0500 (Eastern Standard Time)"

console.log(d.getFullYear()); // 2011

Using new Date(YYYY, MM-1, DD) will ensure you stay in the local zone and the DateTime select won’t sneak in that additional year.

If you still prefer to pass the ISO format, here's a function that can do the conversion

function newLocalDate(date) {
    const parts = date.split('-');   // ["YYYY","MM","DD"]
    const year  = parts[0];
    const month = parts[1] - 1;  // zero-indexed (0 = January)
    const day   = parts[2];      // day-of-month
    
    // Build local-time Date:
    return new Date(year, month, day);
}


...
opts: {
    minDate: newLocalDate('2011-03-01'),
    maxDate: newLocalDate('2011-10-31')
}
...

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 64,557Questions: 1Answers: 10,672 Site admin
    Answer ✓

    Thanks for writing this up. I'll take a look and see what I can do to improve the example :). Dates can be such a pain!

    Allan

Sign In or Register to comment.