Skip to content

Instantly share code, notes, and snippets.

@benlesh
Created August 15, 2014 19:25
Show Gist options
  • Save benlesh/accff2313c7998b65727 to your computer and use it in GitHub Desktop.
Save benlesh/accff2313c7998b65727 to your computer and use it in GitHub Desktop.
Angular Date Parsing Hackery
console.clear();
var $locale = locale;
function forEach(coll, fn) {
var type = Object.prototype.toString.call(coll);
if(type === '[object Array]') {
//HACK new browsers only
coll.forEach(fn);
} else if(type === '[object Object]') {
for(var key in coll) {
fn(coll[key], key, coll);
}
}
}
function filter(coll, fn) {
//HACK: New browsers only
return coll.filter(fn);
}
function getRegexBody(regex) {
return (/^\/(.*)\/.*$/g).exec(''+regex)[1];
}
function isFunction(o) {
return typeof o === 'function';
}
//HACK: only for new browsers
function indexOf(coll, item) {
return coll.indexOf(coll, item);
}
var ISO_TIME = 'HH:mm:ss',
ISO_TIME_UTC = ISO_TIME + 'Z',
ISO_DATE = 'yyyy-MM-dd',
ISO_DATETIME = ISO_DATE + 'T' + ISO_TIME,
ISO_DATETIME_UTC = ISO_DATETIME + 'Z'
var subPatterns = [
['dd', 'day', /[0-9]{2}/],
['d', 'day', /\d+/],
['MMMM', 'fullmonth', monthRegExp],
['MMM', 'shortmonth', shortMonthRegExp],
['MM', 'month', /\d\d/],
['M', 'month', /\d+/],
['yyyy','year',/\d{4}/],
['yy','year',/\d\d/],
['y','year',/\d+/],
['HH','hours',/\d\d/],
['H', 'hours',/\d+/],
['hh', 'hours', /\d\d/],
['h', 'hours', /\d+/],
['mm', 'minutes', /\d\d/],
['m', 'minutes', /\d+/],
['.sss', 'milliseconds', /\.\d\d\d/],
[',sss', 'milliseconds', /,\d\d\d/],
['ss', 'seconds', /\d\d/],
['s', 'seconds', /\d+/],
['Z', 'offset', /[+-]\d\d\d\d/]
];
function collectionRegExp(collection) {
return new RegExp('('+ collection.join('|') + ')');
}
function shortMonthRegExp() {
return collectionRegExp($locale.DATETIME_FORMATS.SHORTMONTH);
}
function monthRegExp() {
return collectionRegExp($locale.DATETIME_FORMATS.MONTH);
}
function createMatcher(pattern) {
var body = pattern,
map = [],
runAfter = null;
forEach(subPatterns, function(sp) {
var pattern = sp[0],
name = sp[1],
regexp = sp[2];
if(isFunction(regexp)) {
body = body.replace(pattern, function(match, index) {
map[index] = name;
return '!@#$';
});
runAfter = runAfter || {};
runAfter[name] = regexp();
} else {
body = body.replace(pattern, function(match, index) {
map[index] = name;
return '(' + getRegexBody(regexp) + ')';
});
}
});
if(runAfter) {
forEach(runAfter, function(regexp, name) {
body = body.replace('!@#$', function(match, index) {
console.log(regexp);
return '(' + getRegexBody(regexp()) + ')';
});
});
}
return {
map: filter(map, function() { return true; }),
regexp: new RegExp('^' + body + '$')
};
}
function parse(str, pattern) {
var matcher = createMatcher(pattern),
matches = matcher.regexp.exec(str),
time;
console.log('test', matcher);
if(matches) {
time = {};
console.log(matcher.map);
forEach(matcher.map, function(name, i) {
var value = matches[i+1],
formats = $locale.DATETIME_FORMATS;
if(name === 'shortmonth') {
time.month = indexOf(formats.SHORTMONTH, value);
} else if (name === 'fullmonth') {
time.month = indexOf(formats.MONTH, value);
} else {
time[name] = +value;
}
});
return new Date(time.year || 0,
time.month ? time.month-1 : 0,
time.day || 1,
time.hours || 0,
time.minutes || 0,
time.seconds || 0);
}
return null;
}
console.log(parse('2013 12 25 01:23:45', 'y MM dd HH:mm:ss'));
console.log(parse('31\u200f//10\u200f//2012', 'dd\u200f//MM\u200f//y'));
console.log(parse('14 Dec 2013', 'dd MMM yyyy'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment