Skip to content

Instantly share code, notes, and snippets.

@ptgolden
Created May 25, 2012 23:30
Show Gist options
  • Save ptgolden/2791172 to your computer and use it in GitHub Desktop.
Save ptgolden/2791172 to your computer and use it in GitHub Desktop.
Validator for Library of Congress's Extended Date/Time Format (Level 1)
var isValidEDTF = function (str) {
var verdict,
intervals = str.split('/'),
validateSingleDate;
validateSingleDate = function(dateString) {
var verdict,
sepMarks = dateString.split(/([?~]*)$/),
dateParts = sepMarks[0].split('-'),
possiblyUnclearYear = /^-?[0-9]{0,2}(?:[0-9]{2}|[0-9]u|uu)$/,
knownYear = /^-?(?:[0-9]{1,4}|y[0-9]{5,})/,
possiblyUnclear = /^(?:[0-9]{2}|uu)$/,
year,
month,
day;
if (dateParts.length == 1) {
// Valid if this is only a year (possibly unclear).
year = dateParts[0];
verdict = possiblyUnclearYear.test(year) || knownYear.test(year)
} else if (dateParts.length == 2) {
// Valid if this is a year (definitely known) and a month (possibly unclear)
year = dateParts[0];
month = dateParts[1];
verdict = knownYear.test(year) && possiblyUnclear.test(month);
if (/[0-9]/.test(month)) {
verdict = ( month >= 1 && month <= 12 ||
month >= 21 && month <= 24 ) && verdict
}
} else if (dateParts.length == 3) {
// Valid is this is a year (definitely known) and one of the following:
// 1. Known month & possibly unclear day
// 2. Unclear month & unclear day
year = dateParts[0];
month = dateParts[1];
day = dateParts[2].split('T')[0]
verdict = knownYear.test(year) &&
( /^[0-9]{2}$/.test(month) && possiblyUnclear.test(day) ) ||
( /^uu$/.test(month) && /^uu$/.test(day) )
if (/[0-9]/.test(month)) {
verdict = ( month >= 1 && month <= 12 ) && verdict
}
if (/[0-9]/.test(day)) {
verdict = ( day >= 1 && day <= 31 ) && verdict
}
} else {
verdict = false;
}
return verdict;
}
/*
* Test one or two dates, depending on if date is an interval.
*/
if (intervals.length == 1) {
verdict = validateSingleDate(intervals[0]);
} else if (intervals.length == 2) {
// The first part of an interval can be 'unknown'; second 'open' or 'unknown'
verdict = ( validateSingleDate(intervals[0]) || /^unknown$/.test(intervals[0]) ) &&
( validateSingleDate(intervals[1]) || /^(?:open|unknown)$/.test(intervals[1]) );
} else {
verdict = false;
}
return verdict;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment