Skip to content

Commit

Permalink
Merge pull request #431 from ravestack/suchchange
Browse files Browse the repository at this point in the history
Leap year and general date validation for isDate().
  • Loading branch information
chriso committed Oct 5, 2015
2 parents fc03288 + eddbd0f commit eecb88f
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 2 deletions.
85 changes: 84 additions & 1 deletion test/validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -855,16 +855,99 @@ describe('Validators', function () {
validator: 'isDate'
, valid: [
'2011-08-04'
, '2011-09-30'
, '04. 08. 2011.'
, '08/04/2011'
, '08/31/2011'
, '2011.08.04'
, '2/29/24'
, '2-29-24'
, '4. 8. 2011. GMT'
, '2. 28. 2011. GMT'
, '2. 29. 2008. GMT'
, '2011-08-04 12:00'
]
, '2/22/23'
, '2-23-22'
, '12'
, '11/2/23 12:24'
, new Date()
, 'Mon Aug 17 2015 00:24:56 GMT-0500 (CDT)'
, '2/22/23 23:24:26'
// valid ISO 8601 dates below
, '2009-12T12:34'
, '2009'
, '2009-05-19'
, '2009-05-19'
, '2009-05'
, '2009-001'
, '2009-05-19'
, '2009-05-19 00:00'
, '2009-05-19 14:31'
, '2009-05-19 14:39:22'
, '2009-05-19T14:39Z'
, '2009-05-19 14:39:22-06:00'
, '2009-05-19 14:39:22+0600'
, '2009-05-19 14:39:22-01'
, '2007-04-06T00:00'
, '2010-02-18T16:23:48.5'
, '200905'
, '2009-'
, '2009-05-19 14:'
, '200912-01'
// RFC 2882 tests below borrowed from the timerep package in Hackage:
// https://hackage.haskell.org/package/timerep-1.0.3/docs/src/Data-Time-RFC2822.html
, 'Fri, 21 Nov 1997 09:55:06 -0600'
, 'Tue, 15 Nov 1994 12:45:26 GMT'
, 'Tue, 1 Jul 2003 10:52:37 +0200'
, 'Thu, 13 Feb 1969 23:32:54 -0330'
, 'Mon, 24 Nov 1997 14:22:01 -0800'
, 'Thu, 13\n Feb\n 1969\n 23:32\n -0330'
, 'Thu, 13\n Feb\n 1969\n 23:32\n -0330 (Newfoundland Time)'
,'24 Nov 1997 14:22:01 -0800'
// slight variations of the above with end-of-month
, 'Thu, 29\n Feb\n 1968\n 13:32\n -0330'
, 'Fri, 30 Nov 1997 09:55:06 -0600'
// more RFC 2882 tests borrowed from libgit2:
// https://github.com/libgit2/libgit2/blob/master/tests/date/rfc2822.c
, 'Wed, 10 Apr 2014 08:21:03 +0000'
, 'Wed, 9 Apr 2014 10:21:03 +0200'
, 'Wed, 9 Apr 2014 06:21:03 -0200'
, 'Wed, 9 Apr 2014 08:21:03 +0000'
]
, invalid: [
'foo'
, '2011-foo-04'
, '2011-09-31'
, '2. 29. 1987. GMT'
, '2. 29. 2011. GMT'
, '2/29/25'
, '2-29-25'
, 'GMT'
//invalid ISO 8601 dates below
, '2009367'
, '2007-04-05T24:50'
, '2009-000'
, '2009-M511'
, '2009M511'
, '2009-05-19T14a39r'
, '2009-05-19T14:3924'
, '2009-0519'
, '2009-05-1914:39'
, '2009-05-19r14:39'
, '2009-05-19 14a39a22'
, '2009-05-19 14:39:22+06a00'
, '2009-05-19 146922.500'
, '2010-02-18T16.5:23.35:48'
, '2010-02-18T16:23.35:48'
, '2010-02-18T16:23.35:48.45'
, '2009-05-19 14.5.44'
, '2010-02-18T16:23.33.600'
, '2010-02-18T16,25:23:48,444'
, '2009-02-30 14:'
, '200912-32'
// hackage RFC2822 variants with invalid end-of-month
, 'Thu, 29\n Feb\n 1969\n 13:32\n -0330'
, 'Fri, 31 Nov 1997 09:55:06 -0600'
]
});
});
Expand Down
29 changes: 28 additions & 1 deletion validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,34 @@
};

validator.isDate = function (str) {
return !isNaN(Date.parse(str));
var normalizedDate = new Date((new Date(str)).toUTCString());
var regularDay = String(normalizedDate.getDate());
var utcDay = String(normalizedDate.getUTCDate());
var dayOrYear, dayOrYearMatches, year;
if (isNaN(Date.parse(normalizedDate))) {
return false;
}
//check for valid double digits that could be late days
//check for all matches since a string like '12/23' is a valid date
//ignore everything with nearby colons
dayOrYearMatches = str.match(/(^|[^:\d])[23]\d([^:\d]|$)/g);
if (!dayOrYearMatches) {
return true;
}
dayOrYear = dayOrYearMatches.map(function(digitString) {
return digitString.match(/\d+/g)[0];
}).join('/');
year = String(normalizedDate.getFullYear()).slice(-2);
//local date and UTC date can differ, but both are valid, so check agains both
if (dayOrYear === regularDay || dayOrYear === utcDay || dayOrYear === year) {
return true;
} else if ((dayOrYear === (regularDay + '/' + year)) || (dayOrYear === (year + '/' + regularDay))) {
return true;
} else if ((dayOrYear === (utcDay + '/' + year)) || (dayOrYear === (year + '/' + utcDay))) {
return true;
} else {
return false;
}
};

validator.isAfter = function (str, date) {
Expand Down

0 comments on commit eecb88f

Please sign in to comment.