diff --git a/src/lib/isRFC3339.js b/src/lib/isRFC3339.js index 48b025e0f..a9a3a0828 100644 --- a/src/lib/isRFC3339.js +++ b/src/lib/isRFC3339.js @@ -21,7 +21,18 @@ const fullTime = new RegExp(`${partialTime.source}${timeOffset.source}`); const rfc3339 = new RegExp(`^${fullDate.source}[ tT]${fullTime.source}$`); +function daysInMonth(year, month) { + if (month === 2) { + return ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) ? 29 : 28; + } + return [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month - 1]; +} + export default function isRFC3339(str) { assertString(str); - return rfc3339.test(str); + if (!rfc3339.test(str)) { + return false; + } + const [, year, month, day] = str.match(/^(\d{4})-(\d{2})-(\d{2})/).map(Number); + return day <= daysInMonth(year, month); } diff --git a/test/validators.test.js b/test/validators.test.js index 3d2c8e8b2..7230c27e3 100644 --- a/test/validators.test.js +++ b/test/validators.test.js @@ -12603,9 +12603,16 @@ describe('Validators', () => { '2010-02-18t00:23:23.33+06:00', '2010-02-18t00:23:32.33+00:00', '2010-02-18t00:23:32.33+23:00', + '2020-02-29T14:39:22Z', + '2000-02-29T00:00:00Z', ], invalid: [ '2010-02-18t00:23:32.33+24:00', + '2021-02-30T00:00:00Z', + '2021-04-31T00:00:00Z', + '2021-06-31T12:00:00Z', + '2021-02-29T00:00:00Z', + '1900-02-29T00:00:00Z', '2009-05-31 14:60:55Z', '2010-02-18t24:23.33+0600', '2009-05-00 1439,55Z',