簡體   English   中英

Javascript 日期和夏令時,添加月份修改小時數

[英]Javascript Date and DST, add months modify hours

我知道這是一個著名的問題,我知道要修改日期,但我找不到與此問題有關的任何信息。

我有一個 ISO 8061 日期,我想在不修改小時和天數的情況下添加/減去月份:

我有以下輸入:

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

我想將 1 個月添加到 add1Month 並將 10 添加到 add10Month 以獲得以下輸出:

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"

提前致謝 !

那個“手工”可以美化一點:

 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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM