Hi. Does anyone know if there is a way to check if a date is valid (eg. 02/30/2000). isValid() seems to return true for this case.
confirmed by isValid('2000-02-30') => true
IMHO, the root cause is new Date() API (that used in toDate -> isValid)
> new Date(2000, 1, 30)
'2000-02-29T17:00:00.000Z'
> new Date(2000, 1, 31)
'2000-03-01T17:00:00.000Z'
> toDate('2000-01-99')
'2000-04-07T17:00:00.000Z'
> toDate('2000-99-01')
'2008-02-29T17:00:00.000Z'
new Date('02/30/2000') will create a valid date, so long as the month [1-12] day [1-31] are within the ranges provided. In the instance of a leap year or a _short_ month, if the day provided exceeds what would be on a calendar and is still within the range, it would increment the month and take the remaining days as the new date.
> new Date('02/30/2000')
'Wed Mar 01 2000 00:00:00 GMT-0800 (PST)'
> new Date('02/33/2000')
'Invalid Date'
> isValid(new Date('02/30/2000'))
true
> isValid(new Date('02/33/2000'))
true
As @nodtem66 mentioned, the cause is how new Date is implemented and the lack of validating within the range [1-31]. It would be best to provide a way to cross-check the month/day between the input and output, but that would mean the user would have to use a strict format when providing the date string/values, as there's more than one way to create a new Date using a string param or numeric params.
update FWIW, if you are passing in a strict format new Date(<mm/dd/yyyy>), you can create your own validation layer to see if the month and/or day has changed similar to this:
function isValidDate(date) {
const d = new Date(date);
let [month, day, year] = date.split('/')
// need to reduce month value by 1 to accommodate new Date formats the month
--month;
if (d.getFullYear() == year && d.getMonth() == month && d.getDate() == day) {
return true;
}
return false;
}
Fixed in v2.0.0-alpha.14 in PR #808
Most helpful comment
Fixed in v2.0.0-alpha.14 in PR #808