Skip to content

Instantly share code, notes, and snippets.

@terrancesnyder
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save terrancesnyder/737fd7712c57233aface to your computer and use it in GitHub Desktop.
Save terrancesnyder/737fd7712c57233aface to your computer and use it in GitHub Desktop.
DateMathParser for JavaScript
var DateMathParser = function() {
return {
parse: function(match) {
var dt = new moment();
if (0 == match.length) {
return dt;
};
var splitter = new RegExp("([^/]*)([/]{0,1})([^\\-\\+]*)(.*)");
var pos = 0;
var ops = _.reject(match.split(splitter), function(d) { return !d; });
// check if first ops is NOW or DATE
var date = ops.shift();
if (date != 'NOW') {
dt = new moment(date);
}
while (pos < ops.length) {
var txt = ops[pos++];
var command = txt.charAt(0);
switch (command) {
case 'N':
// someone provided 'NOW'
break;
case '/':
// rounding date down (using moment)
dt = dt.startOf(ops[pos++].toLowerCase());
break;
case '+': // fall through
case '-':
// extract date math adn apply to current dt
var terms = _.reject(txt.split(new RegExp("([\\-\\+]+)([0-9]+)(.+)")), function(d) { return !d });
var plus_or_minus = terms[0];
var numeric = terms[1];
var part = terms[2];
switch (part) {
case 'DAYS':
part = 'DAY';
break;
case 'HOURS':
part = 'HOUR';
break;
case 'WEEKS':
part = 'WEEK';
break;
case 'MINUTES':
part = 'MINUTE';
break;
case 'SECONDS':
part = 'SECOND';
break;
case 'MILLISECONDS':
part = 'MILLISECOND';
break;
case 'MONTHS':
part = 'MONTH';
break;
case 'YEARS':
part = 'YEAR';
break;
}
if (plus_or_minus == '-') {
dt = dt.subtract(part.toLowerCase(), numeric);
} else {
dt = dt.add(part.toLowerCase(), numeric);
}
break;
default:
throw 'Not parsable';
}
}
return dt;
}
}
};
// usage
var parser = new DateMathParser();
console.log(parser.parse('NOW/DAY')); // does today rounded to 00:00:00
console.log(parser.parse('NOW/MONTH')); // does today rounded to nearest month @ 00:00:00
console.log(parser.parse('NOW/WEEK')); // does today rounded to nearest month @ 00:00:00
console.log(parser.parse('NOW/YEAR')); // does today rounded to nearest month @ 00:00:00
console.log(parser.parse('NOW/DAY+5DAYS')); // does today rounded to nearest day and adds 5 days
console.log(parser.parse('NOW/DAY-5DAYS')); // does today rounded to nearest day and subtracts 5 days
console.log(parser.parse('NOW/DAY+1MONTH')); // does today rounded to nearest day and adds 1 month
console.log(parser.parse('NOW/DAY-1MONTH')); // does today rounded to nearest day and subtracts 1 month
console.log(parser.parse('NOW+1HOUR')); // right now to the second and adds 1 hour
console.log(parser.parse('NOW-1HOUR')); // right now to the second and subtracts 1 hour
console.log(parser.parse('2013-06-28T00:00:00Z+1DAY')); // 1 DAY plus the specified time
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment