Permalink
443f8ae Jun 6, 2016
@ichernev @maggiepint @dhurlburtusa
112 lines (90 sloc) 4.17 KB
title version signature
Validation
1.7.0
moment().isValid();

Moment applies stricter initialization rules than the Date constructor.

new Date(2013, 25, 14).toString(); // "Sat Feb 14 2015 00:00:00 GMT-0500 (EST)"
moment([2015, 25, 35]).format();   // 'Invalid date'

You can check whether the Moment considers the date invalid using moment#isValid. You can check the metrics used by #isValid using moment#parsingFlags, which returns an object.

The following parsing flags result in an invalid date:

  • overflow: An overflow of a date field, such as a 13th month, a 32nd day of the month (or a 29th of February on non-leap years), a 367th day of the year, etc. overflow contains the index of the invalid unit to match #invalidAt (see below); -1 means no overflow.
  • invalidMonth: An invalid month name, such as moment('Marbruary', 'MMMM');. Contains the invalid month string itself, or else null.
  • empty: An input string that contains nothing parsable, such as moment('this is nonsense');. Boolean.
  • nullInput: A null input, like moment(null);. Boolean.
  • invalidFormat: An empty list of formats, such as moment('2013-05-25', []). Boolean.
  • userInvalidated: A date created explicitly as invalid, such as moment.invalid(). Boolean.

    In addition to the above, As of 2.13.0 the meridiem and parsedDateParts flags work together to determine date validity.

  • meridiem: Indicates what meridiem (AM/PM) was parsed, if any. String.
  • parsedDateParts: Returns an array of date parts parsed in descending order - i.e. parsedDateParts[0] === year. If no parts are present, but meridiem has value, date is invalid. Array.

Additionally, if the Moment is parsed in strict mode, these flags must be empty for the Moment to be valid:

  • unusedTokens: array of format substrings not found in the input string
  • unusedInput: array of input substrings not matched to the format string

Note: Moment's concept of validity became more strict and consistent between 2.2 and 2.3.

Additionally, you can use moment#invalidAt to determine which date unit overflowed.

var m = moment("2011-10-10T10:20:90");
m.isValid(); // false
m.invalidAt(); // 5 for seconds

The return value has the following meaning:

  1. years
  2. months
  3. days
  4. hours
  5. minutes
  6. seconds
  7. milliseconds

Note: In case of multiple wrong units the first one is returned (because days validity may depend on month, for example).

Invalid Moments

If a moment is invalid, it behaves like a NaN in floating point operations.

All of the following produce invalid moments:

  • invalid.add(unit, value)
  • another.add(invalid)
  • invalid.clone()
  • invalid.diff(another)
  • invalid.endOf(unit)
  • invalid.max(another)
  • another.max(invalid)
  • invalid.min(another)
  • another.min(invalid)
  • invalid.set(unit, value)
  • invalid.startOf(unit)
  • invalid.subtract(unit, value)

The following produce a localized version of 'InvalidDate':

  • invalid.format(anyFmt) results in 'Invalid Date' in the current locale
  • invalid.from(another)
  • another.from(invalid)
  • invalid.fromNow(suffix)
  • invalid.to(another)
  • another.to(invalid)
  • invalid.toNow(suffix)
  • invalid.toISOString()
  • invalid.toString()

The following return false:

  • invalid.isAfter(another)
  • another.isAfter(invalid)
  • invalid.isBefore(another)
  • another.isBefore(invalid)
  • invalid.isBetween(another, another)
  • invalid.isSame(another)
  • another.isSame(invalid)
  • invalid.isSameOrAfter(another)
  • another.isSameOrAfter(invalid)
  • invalid.isSameOrBefore(another)
  • another.isSameOrBefore(invalid)

And these return null or NaN with some structure:

  • invalid.get(unit) returns null, as all other named getters
  • invalid.toArray() === [NaN, NaN, NaN, NaN, NaN, NaN]
  • invalid.toObject() has all values set to NaN
  • invalid.toDate() returns an invalid Date object
  • invalid.toJSON() returns null
  • invalid.unix() returns null
  • invalid.valueOf() returns null