Skip to content

Commit

Permalink
fix: extra validation for dates
Browse files Browse the repository at this point in the history
This commit adds an additional test for dates
over and above passing the pattern match.

It checks to assertain that the date is a
valid date. For examples, dates like
2009-02-29 are caught as invalid.

Additionally, it also fixes a minor bug
with the `weekDate` that was wrongfully
leaving out W53 as an invalid date.

fixes #772
  • Loading branch information
profnandaa committed Oct 14, 2018
1 parent 43540cd commit c75411b
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Validator | Description
**isISBN(str [, version])** | check if the string is an ISBN (version 10 or 13).
**isISSN(str [, options])** | check if the string is an [ISSN](https://en.wikipedia.org/wiki/International_Standard_Serial_Number).<br/><br/>`options` is an object which defaults to `{ case_sensitive: false, require_hyphen: false }`. If `case_sensitive` is true, ISSNs with a lowercase `'x'` as the check digit are rejected.
**isISIN(str)** | check if the string is an [ISIN][ISIN] (stock/security identifier).
**isISO8601(str)** | check if the string is a valid [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) date.
**isISO8601(str)** | check if the string is a valid [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) date; with additional checks for valid dates, e.g. invalidates dates like `2009-02-29`.
**isRFC3339(str)** | check if the string is a valid [RFC 3339](https://tools.ietf.org/html/rfc3339) date.
**isISO31661Alpha2(str)** | check if the string is a valid [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) officially assigned country code.
**isISO31661Alpha3(str)** | check if the string is a valid [ISO 3166-1 alpha-3](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3) officially assigned country code.
Expand Down
26 changes: 24 additions & 2 deletions lib/isISO8601.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,33 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de

/* eslint-disable max-len */
// from http://goo.gl/0ejHHW
var iso8601 = /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;
var iso8601 = /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-3])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;
/* eslint-enable max-len */
var isValidDate = function isValidDate(str) {
// str must have passed the ISO8601 check
// this check is meant to catch invalid dates
// like 2009-02-31
// note: we choose not to validate the time part
var match = str.match(/(\d{4})-?(\d{0,2})-?(\d{0,2})/).map(Number);
var year = match[1];
var month = match[2];
var day = match[3];
// create a date object and compare
var d = new Date(year + '-' + (month || 1) + '-' + (day || 1));
if (isNaN(d.getFullYear())) return false;
if (month && day) {
return d.getFullYear() === year && d.getMonth() + 1 === month && d.getDate() === day;
}
return true;
};

function isISO8601(str) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { strict: true };

(0, _assertString2.default)(str);
return iso8601.test(str);
var check = iso8601.test(str);
if (!options) return check;
if (check && options.strict) return isValidDate(str);
return check;
}
module.exports = exports['default'];
28 changes: 25 additions & 3 deletions src/lib/isISO8601.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,32 @@ import assertString from './util/assertString';

/* eslint-disable max-len */
// from http://goo.gl/0ejHHW
const iso8601 = /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;
const iso8601 = /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-3])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;
/* eslint-enable max-len */
const isValidDate = (str) => {
// str must have passed the ISO8601 check
// this check is meant to catch invalid dates
// like 2009-02-31
// note: we choose not to validate the time part
const match = str.match(/(\d{4})-?(\d{0,2})-?(\d{0,2})/).map(Number);
const year = match[1];
const month = match[2];
const day = match[3];
// create a date object and compare
const d = new Date(`${year}-${month || 1}-${day || 1}`);
if (isNaN(d.getFullYear())) return false;
if (month && day) {
return d.getFullYear() === year
&& (d.getMonth() + 1) === month
&& d.getDate() === day;
}
return true;
};

export default function isISO8601(str) {
export default function isISO8601(str, options = { strict: true }) {
assertString(str);
return iso8601.test(str);
const check = iso8601.test(str);
if (!options) return check;
if (check && options.strict) return isValidDate(str);
return check;
}
7 changes: 5 additions & 2 deletions test/validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -5419,7 +5419,7 @@ describe('Validators', () => {
'2009123',
'2009-05',
'2009-123',
'2009-222',
// '2009-222', // invalid test-case, implies 2009-22-2
'2009-001',
'2009-W01-1',
'2009-W51-1',
Expand All @@ -5434,7 +5434,7 @@ describe('Validators', () => {
'2009-05-19T14:39Z',
'2009-W21-2',
'2009-W21-2T01:22',
'2009-139',
// '2009-139', // invalid test-case, implies 2009-13-9
'2009-05-19 14:39:22-06:00',
'2009-05-19 14:39:22+0600',
'2009-05-19 14:39:22-01',
Expand Down Expand Up @@ -5476,6 +5476,9 @@ describe('Validators', () => {
'2009-05-19 14.5.44',
'2010-02-18T16:23.33.600',
'2010-02-18T16,25:23:48,444',
'2010-13-1',
'2010-02-30',
'2009-02-29',
],
});
});
Expand Down
26 changes: 24 additions & 2 deletions validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -1236,12 +1236,34 @@ function isCurrency(str, options) {

/* eslint-disable max-len */
// from http://goo.gl/0ejHHW
var iso8601 = /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;
var iso8601 = /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-3])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/;
/* eslint-enable max-len */
var isValidDate = function isValidDate(str) {
// str must have passed the ISO8601 check
// this check is meant to catch invalid dates
// like 2009-02-31
// note: we choose not to validate the time part
var match = str.match(/(\d{4})-?(\d{0,2})-?(\d{0,2})/).map(Number);
var year = match[1];
var month = match[2];
var day = match[3];
// create a date object and compare
var d = new Date(year + '-' + (month || 1) + '-' + (day || 1));
if (isNaN(d.getFullYear())) return false;
if (month && day) {
return d.getFullYear() === year && d.getMonth() + 1 === month && d.getDate() === day;
}
return true;
};

function isISO8601(str) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { strict: true };

assertString(str);
return iso8601.test(str);
var check = iso8601.test(str);
if (!options) return check;
if (check && options.strict) return isValidDate(str);
return check;
}

/* Based on https://tools.ietf.org/html/rfc3339#section-5.6 */
Expand Down
2 changes: 1 addition & 1 deletion validator.min.js

Large diffs are not rendered by default.

0 comments on commit c75411b

Please sign in to comment.