Javascript日期和DST,添加月份修改小时数

时间:2018-10-02 16:40:37

标签: javascript node.js

我知道这是一个著名的问题,我知道要修改日期,但是我找不到与此问题有关的任何东西。

我有一个ISO 8061日期,我想在不修改小时和天的情况下添加/减去月份:

我有以下输入内容:

var add1Month = "2018-10-01T23:59:59.000Z";
var add10Month = "2018-12-01T00:00:00.000Z";

我想在add1Month上添加1个月,在add10Month上添加10个月,以产生以下输出:

var resAdd1Month  = "2018-11-01T23:59:59.000Z";
var resAdd10Month = "2019-10-01T00:00:00.000Z";

请注意,日期和时间没有修改,也没有修改。

通常,我使用夫妇setMonth / getMonth或moment对其进行修改,但是我无法获得很好的效果:

// With date
var add1Month = new Date("2018-10-01T23:59:59.000Z");
add1Month.setMonth(add1Month.getMonth() + 1);
console.log(add1Month.toJSON()); // 2018-11-02T00:59:59.000Z


var add10Month = new Date("2018-12-01T00:00:00.000Z")
add10Month.setMonth(add10Month.getMonth() + 10);
console.log(add10Month.toJSON()); // 2019-09-30T23:00:00.000Z



// With moment
var add1Month = new Date(moment("2018-10-01T23:59:59.000Z").add(1, 'M').format()).toJSON();
console.log(add1Month); // 2018-11-02T00:59:59.000Z

var add10Month = new Date(moment("2018-12-01T00:00:00.000Z").add(10, 'M').format()).toJSON()
console.log(add10Month); // 2019-09-30T23:00:00.000Z

在DST交叉的情况下,有一种简便的方法可以在日期中添加月份而不修改日期或小时?

我现在找到的唯一解决方案是手动添加:

function addMonth(isoDate, month){

  var splitDate = isoDate.substr(0,10).split("-").map(function(e){return parseInt(e)});

   // modify month
   splitDate[1] = splitDate[1]+month;

   // modify year if needed
   splitDate[0] = splitDate[0] + Math.floor((splitDate[1] || -12) / 12);

   // remove extra month aleady added in year and take account negative for month substraction
   splitDate[1] = Math.abs((12 + splitDate[1]) % 12) || 12;

   // reformat with 2 digit month and days
   splitDate[1] = ("00"+splitDate[1]).substr(-2);
   splitDate[2] = ("00"+splitDate[2]).substr(-2);


   // manage end day of month 31/30 => 2018-07-31 - 1 month => 2018-06-31 => 2018-06-30 (remove day until valid date found)
    while(new Date(splitDate[0]+"-"+splitDate[1]+"-"+splitDate[2]+isoDate.substr(10)).toJSON() !=
splitDate[0]+"-"+splitDate[1]+"-"+splitDate[2]+isoDate.substr(10)
   )
   {
     splitDate[2] = parseInt(splitDate[2]) - 1;
     splitDate[2] = ("00"+(splitDate[2])).substr(-2);
   }


   return splitDate[0]+"-"+splitDate[1]+"-"+splitDate[2]+isoDate.substr(10);

}

addMonth("2018-10-01T23:59:59.000Z", 1); // "2018-11-01T23:59:59.000Z"
addMonth("2018-12-01T00:00:00.000Z", 10); // "2019-10-01T00:00:00.000Z"
addMonth("2018-06-01T00:00:00.000Z", -11); // "2017-05-01T00:00:00.000Z"
 addMonth("2018-03-31T23:59:59.000Z", -1); // "2018-02-28T23:59:59.000Z"

谢谢!

1 个答案:

答案 0 :(得分:2)

可以“美化”“手工”:

 function addMonths(date, add) {
  const [day, time] = date.split("T");
  let [years, months, days] = day.split("-");

  months = +months + add;

  years = +years + Math.floor(months / 12);
  months = months % 12;



  return [years, months.padStart(2, 0), days].join("-") + "T" + time;
}