Skip to content

MomentJS - Date Validation

Ensuring that date inputs are valid is crucial for data integrity. Moment.js provides straightforward methods to validate dates created through its parsing functions.

The primary method for checking validity is .isValid(). It returns true if the Moment object represents a valid date and false otherwise.

// Valid Dates
console.log(moment('2023-10-26').isValid()); // true
console.log(moment('26/10/2023', 'DD/MM/YYYY').isValid()); // true
console.log(moment({ year: 2024, month: 1, day: 29 }).isValid()); // true (Feb 29, 2024 is valid)
// Invalid Dates
console.log(moment('Invalid Date String').isValid()); // false
console.log(moment('2023-13-01', 'YYYY-MM-DD').isValid()); // false (invalid month)
console.log(moment('2023-02-29', 'YYYY-MM-DD').isValid()); // false (2023 not a leap year)
console.log(moment('26/10/2023', 'YYYY-MM-DD').isValid()); // false (format mismatch)

When isValid() returns false, you can often get more information about why the date is invalid by inspecting the parsing flags available via moment().parsingFlags(). This returns an object containing several helpful flags:

Flag NameDescription
overflowIndicates an overflow for a particular unit (e.g., month 13, day 32). Returns the index of the overflowing unit (see table below) or -1 if no overflow.
invalidMonthContains the invalid month name string if parsing failed due to an unrecognized month name (e.g., when parsing ‘26 Foo 2023’). Otherwise, null.
invalidFormatBoolean. true if parsing failed because the input string didn’t match the specified format(s).
emptyBoolean. true if the input string contained nothing parsable as a date (e.g., moment('abc')).
nullInputBoolean. true if the input was explicitly null (e.g., moment(null)).
userInvalidatedBoolean. true if the date was created as explicitly invalid using moment.invalid().
meridiemString (‘AM’/‘PM’) or null. Indicates the meridiem parsed, if any.
parsedDatePartsArray. Contains the date parts successfully parsed from the input before an invalidity was detected (e.g., [2023, 12] if parsing ‘2023-13-01’). Useful for debugging overflows.

The .invalidAt() method is a shortcut to identify the unit that caused an overflow. It returns an index corresponding to the overflowing unit:

IndexUnit
0years
1months
2days
3hours
4minutes
5seconds
6milliseconds

If the date is valid or invalid for reasons other than overflow (like format mismatch), invalidAt() returns -1.

const m1 = moment('2023-18-10', 'YYYY-MM-DD');
console.log('m1 isValid:', m1.isValid()); // Output: m1 isValid: false
console.log('m1 invalidAt:', m1.invalidAt()); // Output: m1 invalidAt: 1 (month overflow)
console.log('m1 parsingFlags:', m1.parsingFlags()); // Shows overflow: 1, parsedDateParts: [2023, 17, 10]
const m2 = moment('99/99/9999', 'DD/MM/YYYY');
console.log('m2 isValid:', m2.isValid()); // Output: m2 isValid: false
console.log('m2 invalidAt:', m2.invalidAt()); // Output: m2 invalidAt: 1 (month 99 is invalid)
const m3 = moment('This is not a date');
console.log('m3 isValid:', m3.isValid()); // Output: m3 isValid: false
console.log('m3 invalidAt:', m3.invalidAt()); // Output: m3 invalidAt: -1
console.log('m3 parsingFlags:', m3.parsingFlags()); // Shows empty: true
const m4 = moment('2023-10-26', 'DD/MM/YYYY'); // Format mismatch
console.log('m4 isValid:', m4.isValid()); // Output: m4 isValid: false
console.log('m4 invalidAt:', m4.invalidAt()); // Output: m4 invalidAt: -1
console.log('m4 parsingFlags:', m4.parsingFlags()); // Shows invalidFormat: true

By combining isValid() with invalidAt() and parsingFlags(), you can effectively diagnose issues with date inputs.

Refer to the docs for more details: https://momentjs.com/docs/#/parsing/is-valid/