本分只简单实现了增加 月份 和 天数 的功能,减法功能暂时没做,读者可以自己简单实现。
年份的计算更简单,只需要看增减后是否为闰年,如果是闰年的话看看月份是否为二月,如果为二月的话看看日期是否为合理并相应地调整即可。
天数的加减我看了网上的大部分方法都不是很完美,考虑的都比较少,我暂时只用到了增加天数的部分,就只写了增加天数,这个版本减少天数会出现意想不到的结果,如有需要请评论。
为了方便我为String类型变量增加了endWith方法用来判断字符串结尾字符(M代表增减月份,Y代表增减年份,D代表增减天数)。
// 为String类型变量增加endWith方法用于判断字符串的结尾
String.prototype.endWith=function(endStr){
var d=this.length-endStr.length;
return (d>=0&&this.lastIndexOf(endStr)==d)
}
// 小于10的数字前加0
function formatSmallNum (num) {
var newnum = parseInt(num);
if (newnum<10) { // 调整日小于10时的格式
newnum = 0 + '' + newnum;
}
return newnum
}
var monthbs = [1,0,1,0,1,0,1,1,0,1,0,1] // 定义月份的大小
// 处理加减月时,当日大于28时,将新的日在新的月份中合理化
function adjustNewDay (newyear, newmonth, newday) {
var newAdjustedDay = newday;
if (monthbs[newmonth-1]<1&&newday>28) { // 将新的日在新的月份中合理化
if (newmonth!=2) { // 不是二月时
newAdjustedDay = 30
} else {
if ((newyear % 4 == 0) && (newyear % 100 != 0 || newyear % 400 == 0)) { // 二月时判断是否为闰年
newAdjustedDay = 29
} else {
newAdjustedDay = 28
}
}
}
return newAdjustedDay;
}
// 获取当月份最大天数
function getMonthMaxDays (newyear, month) {
var newmonthdays = 31;
if (monthbs[month-1]<1) {
if (month!=2) {
newmonthdays = 30
} else {
if ((newyear % 4 == 0) && (newyear % 100 != 0 || newyear % 400 == 0)) { // 二月时判断是否为闰年
newmonthdays = 29
} else {
newmonthdays = 28
}
}
}
return newmonthdays;
}
// 用来计算增减天数的递归
function recursionDays (year, month, day, delayTime) {
console.log(year, month, day, delayTime)
var newyear = year;
var newmonth = month;
var newday = day + delayTime;
var newmonthdays = getMonthMaxDays(year, month);
if(newday<=newmonthdays){
newmonth = formatSmallNum(newmonth)
newday = formatSmallNum(newday)
return newyear + "" + newmonth + "" + newday
} else {
newmonthdays = getMonthMaxDays(year, month); // 目标月最大天数
newmonth = month + 1;
newdelay = newday - newmonthdays;
newday = 0;
if (newmonth>12) {
newyear = newyear + 1;
newmonth = newmonth - 12;
}
return recursionDays(newyear, newmonth, newday, newdelay)
}
}
// 日期计算
function addTime(date, delay) {
var monthbs = [1,0,1,0,1,0,1,1,0,1,0,1] // 定义月份的大小
var year = parseInt(date.substring(0, 4)); // 获取年
var month = parseInt(date.substring(4, 6)); // 获取月
var day = parseInt(date.substring(6, 8)); // 获取日
if (delay.endWith("M")) { // 处理月份加
delayTime = parseInt(delay.substring(0,delay.length-1)) // 获取要加的月数
var newyear = year
var newmonth = month + delayTime;
var newday = day;
if (newmonth > 12) { // 月份加后大于12
var newyear = newyear + 1;
var newmonth = newmonth - 12;
}
newday = adjustNewDay(newyear, newmonth, newday);
newmonth = formatSmallNum(newmonth);
newday = formatSmallNum(newday);
var newdate = newyear + "" + newmonth + "" + newday; // 组装新日期
}
if (delay.endWith("D")) { // 处理天数加
delayTime = parseInt(delay.substring(0,delay.length-1)) // 获取要加的天数
var newdate = recursionDays(year,month,day,delayTime); // 通过递归方式计算delayTime天后的日期
}
return newdate;
}
由于需求不同,读者使用时应按照自己需要的格式调整返回值及具体细节。
在参考代码中 addTime 方法第一个参数传入的日期应为 20180810 这种格式的日期,第二个参数应为 3M (三个月)、 15M (十五个月)、 5Y (五年)、 520D (五百二十天)等格式。且代码中的返回值格同样为 20180810 这样的格式。