Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle RFC 2822 timezones in isDate() #447

Merged
merged 5 commits into from
Oct 27, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions test/validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,11 @@ describe('Validators', function () {
, 'Tue, 1 Jul 2003 10:52:37 +0200'
, 'Thu, 13 Feb 1969 23:32:54 -0330'
, 'Mon, 24 Nov 1997 14:22:01 -0800'
, 'Mon Sep 28 1964 00:05:49 GMT+1100 (AEDST)'
, 'Mon Sep 28 1964 00:05:49 +1100 (AEDST)'
, 'Mon Sep 28 1964 00:05:49 +1100'
, 'Mon Sep 28 1964 00:05:49 \nGMT\n+1100\n'
, 'Mon Sep 28 1964 00:05:49 \nGMT\n+1100\n(AEDST)'
, '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'
Expand Down
76 changes: 46 additions & 30 deletions validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -471,40 +471,60 @@
};

function getTimezoneOffset(str) {
var iso8601Parts = str.match(iso8601);
var iso8601Parts = str.match(iso8601)
, timezone, sign, hours, minutes;
if (!iso8601Parts) {
return new Date().getTimezoneOffset();
}
var timezone = iso8601Parts[21];
if (!timezone || timezone === 'z' || timezone === 'Z') {
return 0;
}
var sign = iso8601Parts[22], hours, minutes;
if (timezone.indexOf(':') !== -1) {
hours = parseInt(iso8601Parts[23]);
minutes = parseInt(iso8601Parts[24]);
str = str.toLowerCase();
timezone = str.match(/(?:\s|gmt\s*)(-|\+)(\d{1,4})(\s|$)/);
if (!timezone) {
return str.indexOf('gmt') !== -1 ? 0 : null;
}
sign = timezone[1];
var offset = timezone[2];
if (offset.length === 3) {
offset = '0' + offset;
}
if (offset.length <= 2) {
hours = 0;
minutes = parseInt(offset);
} else {
hours = parseInt(offset.slice(0, 2));
minutes = parseInt(offset.slice(2, 4));
}
} else {
hours = 0;
minutes = parseInt(iso8601Parts[23]);
timezone = iso8601Parts[21];
if (!timezone || timezone === 'z' || timezone === 'Z') {
return 0;
}
sign = iso8601Parts[22];
if (timezone.indexOf(':') !== -1) {
hours = parseInt(iso8601Parts[23]);
minutes = parseInt(iso8601Parts[24]);
} else {
hours = 0;
minutes = parseInt(iso8601Parts[23]);
}
}
return (hours * 60 + minutes) * (sign === '-' ? 1 : -1);
}

validator.isDate = function (str) {
var normalizedDate = new Date((new Date(str)).toUTCString());
var utcDay = String(normalizedDate.getUTCDate());
var normalizedDate = new Date(Date.parse(str));
if (isNaN(normalizedDate)) {
return false;
}
// normalizedDate is in the user's timezone. Apply the input
// timezone offset to the date so that the year and day match
// the input
var timezoneDifference = normalizedDate.getTimezoneOffset() -
getTimezoneOffset(str);
normalizedDate = new Date(normalizedDate.getTime() +
60000 * timezoneDifference);
var regularDay = String(normalizedDate.getDate());
var timezoneOffset = getTimezoneOffset(str);
if (timezoneOffset !== null) {
var timezoneDifference = normalizedDate.getTimezoneOffset() -
timezoneOffset;
normalizedDate = new Date(normalizedDate.getTime() +
60000 * timezoneDifference);
}
var day = String(normalizedDate.getDate());
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
Expand All @@ -516,16 +536,12 @@
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) {
if (dayOrYear === day || dayOrYear === year) {
return true;
} else if ((dayOrYear === (regularDay + '/' + year)) || (dayOrYear === (year + '/' + regularDay))) {
} else if ((dayOrYear === (day + '/' + year)) || (dayOrYear === (year + '/' + day))) {
return true;
} else if ((dayOrYear === (utcDay + '/' + year)) || (dayOrYear === (year + '/' + utcDay))) {
return true;
} else {
return false;
}
return false;
};

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