Quantcast
Channel: Detecting an "invalid date" Date instance in JavaScript - Stack Overflow
Viewing all articles
Browse latest Browse all 58

Answer by Regular Jo for Detecting an "invalid date" Date instance in JavaScript

$
0
0

Do not depend on new Date().

All of these but the last fails. They create date objects, just not on the date you expect.

console.log(new Date(2023,02,35))console.log(new Date(2023,02,29))console.log(new Date(2023,01,29))console.log(new Date(2024,02,39))console.log(new Date(Date.parse('2023-02-30')))console.log(new Date(Date.parse('2023-02-29')))console.log(new Date(Date.parse('2023-02-31')))console.log(new Date(Date.parse('2023-02-32'))) // fails (null)

So I wrote a function that actually validates the date, with a few more features

type ns = number | `${number}`;class SiteDateLib {    static validate(_options: {        /** two digit years will create a date in the year 19xx by native-default. This can override that. You can also change the default value of options.defaultCentury to 20 or whatever you like */        defaultCentury?: ns,        yearMustStartWith?: ns    } | ns, ...parts: [year?: ns, _month?: ns, day?: ns, hour?: ns, minute?: ns, second?: ns]) {        if (!/^\d+/.test(parts.join(''))) return null;        const hasOptions = typeof _options === 'object';        const options = hasOptions ? _options : {};        options.defaultCentury = options.yearMustStartWith ?? options.defaultCentury ?? 19;        let _year = `${hasOptions ? parts.shift() : _options}`;        if (_year.length < 3) {            _year = _year.padStart(4, `${options.defaultCentury}0`);        }        if (options.yearMustStartWith && !_year.startsWith(options.yearMustStartWith)) {            return null;        }        //day cannot be 0        if ((''+parts[1]) === '0') return null;        const [_month, _day, hour, minute, second] = [...parts, 0, 0, 0, 0, 0].map((v) => +(v || 0));        const day = _day || 1        const month = _month - 1;        const year = +_year        const date = new Date(year, month, day, hour, minute, second);        switch (true) {            case date.getFullYear() !== year:            case parts[0] && date.getMonth() !== month:            case parts[1] && date.getDate() !== day:            case parts[2] !== undefined && date.getHours() !== hour:            case parts[3] !== undefined && date.getMinutes() !== minute:            case parts[4] !== undefined && date.getSeconds() !== second:                return null        }        return isNaN(+date) ? null : date;    }};//test SiteDateLib.validate with bad tests like negative numbers and numbers too high...// Good Testsconsole.log('good', SiteDateLib.validate(2021, 5, 31, 23, 59, 59)?.toString()) // Should return a Date objectconsole.log('good', SiteDateLib.validate(4, 1, 1, 0, 0, 0)?.toString()) // Should return a Date objectconsole.log('good', SiteDateLib.validate(2021, 6, 15)?.toString()) // Should return a Date objectconsole.log('good', SiteDateLib.validate(2021, 6, 15, 14, 30)?.toString()) // Should return a Date objectconsole.log('good', SiteDateLib.validate(2020, 2, 29)?.toString()) // Leap year valid date, should return a Date objectconsole.log('good', SiteDateLib.validate(2000, 2, 29, 12, 0, 0)?.toString()) // Century leap year, should return a Date objectconsole.log('good', SiteDateLib.validate(2021, 11, 30)?.toString()) // End of month, should return a Date objectconsole.log('good', SiteDateLib.validate(2021, 7, 4, 9, 15)?.toString()) // Valid date and time, should return a Date objectconsole.log('good', SiteDateLib.validate(1999, 12, 31, 23, 59, 59)?.toString()) // Y2K eve, should return a Date objectconsole.log('good', SiteDateLib.validate({ yearMustStartWith: 19 }, 22, 3, 15, 8)?.toString()) // Valid date with hour, should return a Date object// Bad Testsconsole.log('bad', SiteDateLib.validate(2021, 2, 29, 1, 1, 1)?.toString()) // Invalid date, should return nullconsole.log('bad', SiteDateLib.validate(20213, 1, 32, 1, 1, 1)?.toString()) // Invalid date, should return nullconsole.log('bad', SiteDateLib.validate(2021, 13, 1, 1, 1, 1)?.toString()) // Invalid month, should return nullconsole.log('bad', SiteDateLib.validate(21, 0, 1, 1, 1, 1)?.toString()) // Invalid month, should return nullconsole.log('bad', SiteDateLib.validate(6, 1, 35, 1, 1, 1)?.toString()) // Invalid year, should return nullconsole.log('bad', SiteDateLib.validate(16, 94, 1, 1, 1, 1)?.toString()) // Invalid month, should return nullconsole.log('bad', SiteDateLib.validate(24, -3, 1, 1, 1, 1)?.toString()) // Invalid day, should return nullconsole.log('bad', SiteDateLib.validate(23, 29, 1, 1, "hour", 1, 1)?.toString()) // Invalid hour, should return nullconsole.log('bad', SiteDateLib.validate(2021, 1, 1, 1, "minute", 1)?.toString()) // Invalid minute, should return nullconsole.log('bad', SiteDateLib.validate(2021, 1, 1, 1, 1, "second")?.toString()) // Invalid seconds, should return null

Viewing all articles
Browse latest Browse all 58

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>