Created
August 15, 2014 19:25
-
-
Save benlesh/accff2313c7998b65727 to your computer and use it in GitHub Desktop.
Angular Date Parsing Hackery
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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