Примечание Вы должны быть немного осторожны с арифметикой дат, поскольку она не симметрична и может давать странные результаты, например, 29 февраля 2016 года + 1 год дает 1 марта 2017 года, а 31 июля минус 1 месяц равен 1Июль, поскольку нет 31 июня, он переносится на июль и т. Д.
Учитывая ваши исходные требования, вы можете рассмотреть синтаксический анализатор для вашего конкретного формата, например
function myParse(s, date) {
date = date || new Date();
// Default values object
var values = {
year:{sign:1, value:0}, month:{sign:1, value:0}, day:{sign:1, value:0}
};
// Tokenise string
var part = s.toLowerCase().match(/[a-z]+|\d+|[+-]/ig);
// Process the tokens
if (part) {
for (var i=0, iLen=part.length; i<iLen; i++) {
if (part[i] in values) {
values[part[i]].sign = part[i+1] == '+'? 1 : -1;
values[part[i]].value = +part[i+2];
i += 2;
}
}
}
// Apply to date
date.setFullYear(
date.getFullYear() + values.year.sign * values.year.value,
date.getMonth() + values.month.sign * values.month.value,
date.getDate() + values.day.sign * values.day.value
);
return date;
}
// Examples
var options = {day:'2-digit',month:'short',year:'numeric'};
console.log('Today is ' + (new Date().toLocaleString('en-gb', options)));
['year+1,month+1,day+1', // one of each
'year+2,day+2', // missing parameters
'day + 15, month +2', // any order, random whitespace
'month - 3' // subtraction
].forEach(function(s) {
console.log(s + '\n' + myParse(s).toLocaleString('en-gb', options));
});
Это довольно терпимо, но вы должны проверить ввод.Он может быть расширен и для обработки времени, и для проблем на конец месяца, указанных выше.