如何在JavaScript之前的三个月之前计算日期?


147

我正在尝试形成一个比当前日期早3个月的日期。我通过以下代码获得当月

var currentDate = new Date();
var currentMonth = currentDate.getMonth()+1;

你们能为我提供计算和形成日期的逻辑吗? Date考虑到当月份为1月(1)时,日期前3个月为10月(10月),数据类型)吗?

Answers:


323
var d = new Date();
d.setMonth(d.getMonth() - 3);

这适用于一月。运行以下代码段:

var d = new Date("January 14, 2012");
console.log(d.toLocaleDateString());
d.setMonth(d.getMonth() - 3);
console.log(d.toLocaleDateString());


有一些警告...

一个月是一个奇怪的事情。您如何定义1个月?30天?大多数人会说一个月前是指上个月的同一天需要引用。但是有一半以上的时间,即31天前,而不是30天。如果今天是该月的31号(并且不是8月或12月),则该月的这一天不在上个月。

有趣的是,如果您询问JavaScript 是哪一天前一天,那么Google同意JavaScript

Google搜索结果“ 3月31日之前一个月”显示“ 3月3日”

它也说 一个月为30.4167天Google搜索结果中“一个月内的天数”显示为“ 30.4167”

那么,3月31日之前的一个月与3月28日之前的3个月之前的同一天是吗?这一切都取决于您所说的“一个月前”。去与您的产品所有者进行对话。

如果您想做一下momentjs,并通过移至一个月的最后一天来更正这些月的最后一天错误,则可以执行以下操作:

const d = new Date("March 31, 2019");
console.log(d.toLocaleDateString());
const month = d.getMonth();
d.setMonth(d.getMonth() - 1);
while (d.getMonth() === month) {
    d.setDate(d.getDate() - 1);
}
console.log(d.toLocaleDateString());

如果您的要求比这更复杂,请使用一些数学并编写一些代码。您是开发人员!您无需安装库!您不必从stackoverflow复制和粘贴!您可以自己开发代码以精确完成所需的工作!


var currentDate = new Date(); var currentMonth = currentDate.getMonth()-12; var pastDate = new Date(2011,currentMonth,01); 警报(pastDate); 这项工作经过12个月的检查
KeenUser 2011年

这是一个错误的答案...我将从哪里获得2012,0,15?转换现有的月份-1?
Alex G

3
@AlexG-如果您不熟悉JavaScript日期解析,那么我可以看到我的快速示例令人困惑。JavaScript将月份表示为从零开始的数字,其中一月为零。为了避免这种混乱,尤其是因为这与问题或答案无关,我更新了演示程序,以从字符串中获取日期,这应该更直观。
gilly3,2015年

7
我知道这很旧,但是如果日期是3月31日,并且您使用此方法减去一个月,则结果是3月2日。 jsfiddle.net/atamata/rvumf7dg
atamata

@atamata-是的,这很奇怪,但是可以预见并且可以预期。3月的前一个月结束后的31天是3月31日,但是2月的是3月2日。如果要从该月末开始计数,则必须为此编写一些自定义代码。
gilly3

28

我建议使用一个名为Moment.js的库。

它经过了良好的测试,可以在浏览器和服务器端运行(我在Angular和Node项目中都使用了它)。它对语言环境日期有很大的支持。

http://momentjs.com/

var threeMonthsAgo = moment().subtract(3, 'months');

console.log(threeMonthsAgo.format()); // 2015-10-13T09:37:35+02:00

.format()返回以ISO 8601格式格式化的日期的字符串表示形式。您还可以将其与自定义日期格式一起使用,如下所示:.format('dddd, MMMM Do YYYY, h:mm:ss a')


10

直接放入变量中的“一个衬里”(在多行中易于阅读):

var oneMonthAgo = new Date(
    new Date().getFullYear(),
    new Date().getMonth() - 1, 
    new Date().getDate()
);

真好!不知道它是否适用于每种情况,但似乎可以正常工作。
Devin Fields,


8

这应该处理加法/减法,只需将一个负值减去并添加一个正值即可。这也解决了月份交叉问题。

function monthAdd(date, month) {
    var temp = date;
    temp = new Date(date.getFullYear(), date.getMonth(), 1);
    temp.setMonth(temp.getMonth() + (month + 1));
    temp.setDate(temp.getDate() - 1); 

    if (date.getDate() < temp.getDate()) { 
        temp.setDate(date.getDate()); 
    }

    return temp;    
}

6

如果setMonthgilly3提供的方法不是您想要的方法,请考虑:

var someDate = new Date(); // add arguments as needed
someDate.setTime(someDate.getTime() - 3*28*24*60*60);
// assumes the definition of "one month" to be "four weeks".

可以使用任何时间,只需设置正确的倍数即可。


我会同意gilly3的回答。您假设每月固定的秒数。JavaScript宽大的日期算法将使日期保持正确。9月28日之前的三个月应该是7月28日
雷特里

1
我不知道JavaScript将计算3月31日减去1个月后的结果。
Niet the Dark Absol

1
在这种情况下,您确实会获得3月3日(适用于2011年),因为2月31日就是宽松模式。但是减去2个月,您将获得1月31日。在每月28天的模型下,您不会。尽管Date该类很弱,并且最好使用Date.js,但它至少可以建模一个宽大的日历,足够休闲使用。
雷·托尔

您难道不应该将秒数精确到1000 setTime()吗?
弗拉德·谢佩列夫

4

我喜欢gilly3答案的简单性,但用户可能会感到惊讶,因为3月31日之前的一个月是3月3日。我选择实施一个坚持到月底的版本,因此,在3月28日,29日,30日之前的一个月,而当不是a年时,31日将是2月28日。

function addMonths(date, months) {
  var result = new Date(date),
      expectedMonth = ((date.getMonth() + months) % 12 + 12) % 12;
  result.setMonth(result.getMonth() + months);
  if (result.getMonth() !== expectedMonth) {
    result.setDate(0);
  }
  return result;
}

var dt2004_05_31 = new Date("2004-05-31 0:00"),
    dt2001_05_31 = new Date("2001-05-31 0:00"),
    dt2001_03_31 = new Date("2001-03-31 0:00"),
    dt2001_02_28 = new Date("2001-02-28 0:00"),
    result = addMonths(dt2001_05_31, -2);
console.assert(dt2001_03_31.getTime() == result.getTime(), result.toDateString());

result = addMonths(dt2001_05_31, -3);
console.assert(dt2001_02_28.getTime() == result.getTime(), result.toDateString());

result = addMonths(dt2001_05_31, 36);
console.assert(dt2004_05_31.getTime() == result.getTime(), result.toDateString());

result = addMonths(dt2004_05_31, -38);
console.assert(dt2001_03_31.getTime() == result.getTime(), result.toDateString());

console.log('Done.');


2

已经有一个不错的答案,但是我发现它很难看懂,所以我做了自己的功能。出于我的目的,我不需要否定的结果,但是修改起来并不难。

    var subtractMonths = function (date1,date2) {
        if (date1-date2 <=0) {
            return 0;
        }
        var monthCount = 0;
        while (date1 > date2){
            monthCount++;
            date1.setMonth(date1.getMonth() -1);
        }
        return monthCount;
    }

2

var d = new Date("2013/01/01");
console.log(d.toLocaleDateString());
d.setMonth(d.getMonth() + 18);
console.log(d.toLocaleDateString());


1

这是最小和最简单的代码。

   var minDate = new Date(); 
   minDate.setMonth(minDate.getMonth() - 3);

声明具有当前日期的变量。然后只需使用setMonth内置函数,我们就能获得3个月的追溯日期。


-1

就我而言,我需要减去1个月到当前日期。重要的是月份号,所以它不在乎您上个月需要在当前月份的哪一天。这是我的代码:

var dateObj = new Date('2017-03-30 00:00:00'); //Create new date object
console.log(dateObj); // Thu Mar 30 2017 00:00:00 GMT-0300 (ART)

dateObj.setDate(1); //Set first day of the month from current date
dateObj.setDate(-1); // Substract 1 day to the first day of the month

//Now, you are in the last month
console.log(dateObj); // Mon Feb 27 2017 00:00:00 GMT-0300 (ART)

将1个月减去实际日期是不准确的,这就是为什么我将第一个月的第一天设置为第一天(每个月的第一天始终是第一天),然后我将1天减去第二天,这总是将您发送到上个月。希望能帮助您。

var dateObj = new Date('2017-03-30 00:00:00'); //Create new date object
console.log(dateObj); // Thu Mar 30 2017 00:00:00 GMT-0300 (ART)

dateObj.setDate(1); //Set first day of the month from current date
dateObj.setDate(-1); // Substract 1 day to the first day of the month

//Now, you are in the last month
console.log(dateObj); // Mon Feb 27 2017 00:00:00 GMT-0300 (ART)


-1

   

 var date=document.getElementById("date");
    var d = new Date();
   document.write(d + "<br/>");
    d.setMonth(d.getMonth() - 6);
    document.write(d);

 if(d<date)
  document.write("lesser then 6 months");
else
  document.write("greater then 6 months");


-1

传递JS Date对象和要添加/减去多少个月的整数。monthsToAdd可以是正数或负数。返回一个JS日期对象。

如果您originalDateObject是3月31日,并且将-1传递为monthsToAdd,则输出日期将为2月28日。

如果您经过大量月份(例如36),则它也会正确处理年份调整。

const addMonthsToDate = (originalDateObject, monthsToAdd) => {
  const originalDay = originalDateObject.getUTCDate();
  const originalMonth = originalDateObject.getUTCMonth();
  const originalYear = originalDateObject.getUTCFullYear();

  const monthDayCountMap = {
    "0": 31,
    "1": 28,
    "2": 31,
    "3": 30,
    "4": 31,
    "5": 30,
    "6": 31,
    "7": 31,
    "8": 30,
    "9": 31,
    "10": 30,
    "11": 31
  };

  let newMonth;
  if (newMonth > -1) {
    newMonth = (((originalMonth + monthsToAdd) % 12)).toString();
  } else {
    const delta = (monthsToAdd * -1) % 12;
    newMonth = originalMonth - delta < 0 ? (12+originalMonth) - delta : originalMonth - delta;
  }

  let newDay;

  if (originalDay > monthDayCountMap[newMonth]) {
    newDay = monthDayCountMap[newMonth].toString();
  } else {
    newDay = originalDay.toString();
  }

  newMonth = (+newMonth + 1).toString();

  if (newMonth.length === 1) {
    newMonth = '0' + newMonth;
  }

  if (newDay.length === 1) {
    newDay = '0' + newDay;
  }

  if (monthsToAdd <= 0) {
    monthsToAdd -= 11;
  }

  let newYear = (~~((originalMonth + monthsToAdd) / 12)) + originalYear;

  let newTime = originalDateObject.toISOString().slice(10, 24);

  const newDateISOString = `${newYear}-${newMonth}-${newDay}${newTime}`;

  return new Date(newDateISOString);
};

-5
Following code give me Just Previous Month From Current Month even the date is 31/30 of current date and last month is 30/29/28 days:

   <!DOCTYPE html>
<html>
<body>

<p>Click the button to display the date after changing the month.</p>

<button onclick="myFunction()">Try it</button>

<p id="demo"></p>

<script>
function myFunction() {

var d = new Date("March 29, 2017"); // Please Try the result also for "March 31, 2017" Or "March 30, 2017"
var OneMonthBefore =new Date(d);

OneMonthBefore.setMonth(d.getMonth(),0);
if(OneMonthBefore.getDate() < d.getDate()  )
{
d.setMonth(d.getMonth(),0);
}else
{
d.setMonth(d.getMonth()-1);

}

    document.getElementById("demo").innerHTML = d;
}
</script>

</body>
</html>

该答案与已有的其他7个非常古老的答案有何不同?
Stephen Rauch

-5

var d = new Date();
document.write(d + "<br/>");
d.setMonth(d.getMonth() - 6);
document.write(d);

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.