How do I calculate the date in JavaScript three months prior to today?

JavascriptDate

Javascript Problem Overview


I Am trying to form a date which is 3 months before the current date. I get the current month by the below code

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

Can you guys provide me the logic to calculate and form a date (an object of the Date data type) considering that when the month is January (1), 3 months before date would be OCtober (10)?

Javascript Solutions


Solution 1 - Javascript

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

This works for January. Run this snippet:

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


There are some caveats...

A month is a curious thing. How do you define 1 month? 30 days? Most people will say that one month ago means the same day of the month on the previous month citation needed. But more than half the time, that is 31 days ago, not 30. And if today is the 31st of the month (and it isn't August or Decemeber), that day of the month doesn't exist in the previous month.

Interestingly, Google agrees with JavaScript if you ask it what day is one month before another day:

Google search result for 'one month before March 31st' shows 'March 3rd'

It also says that one month is 30.4167 days long: Google search result for 'one month in days' shows '30.4167'

So, is one month before March 31st the same day as one month before March 28th, 3 days earlier? This all depends on what you mean by "one month before". Go have a conversation with your product owner.

If you want to do like momentjs does, and correct these last day of the month errors by moving to the last day of the month, you can do something like this:

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());

If your requirements are more complicated than that, use some math and write some code. You are a developer! You don't have to install a library! You don't have to copy and paste from stackoverflow! You can develop the code yourself to do precisely what you need!

Solution 2 - Javascript

I recommend using a library called Moment.js.

It is well tested, works cross browser and on server side(I am using it both in Angular and Node projects). It has great support for locale dates.

<http://momentjs.com/>

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

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

.format() returns string representation of date formatted in https://en.wikipedia.org/wiki/ISO_8601">ISO 8601 format. You can also use it with custom date format like this:.format('dddd, MMMM Do YYYY, h:mm:ss a')

Solution 3 - Javascript

A "one liner" (on many line for easy read)) to be put directly into a variable:

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

Solution 4 - Javascript

To make things really simple you can use DateJS, a date library for JavaScript:

http://www.datejs.com/

Example code for you:

Date.today().add({ months: -1 });

Solution 5 - Javascript

This should handle addition/subtraction, just put a negative value in to subtract and a positive value to add. This also solves the month crossover problem.

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

Solution 6 - Javascript

If the setMonth method offered by gilly3 isn't what you're looking for, consider:

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".

Can be used for any amount of time, just set the right multiples.

Solution 7 - Javascript

Do this

 let currentdate = new Date();
 let last3months = new Date(currentdate.setMonth(currentdate.getMonth()-3));

Javascript's setMonth method also takes care of the year. For instance, the above code will return 2020-01-29 if currentDate is set as new Date("2020-01-29")

Solution 8 - Javascript

I like the simplicity of gilly3's answer, but users will probably be surprised that a month before March 31 is March 3. I chose to implement a version that sticks to the end of the month, so a month before March 28, 29, 30, and 31 will all be Feb 28 when it's not a leap year.

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.');

Solution 9 - Javascript

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

Solution 10 - Javascript

There is an elegant answer already but I find that its hard to read so I made my own function. For my purposes I didn't need a negative result but it wouldn't be hard to modify.

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

Solution 11 - Javascript

As I don't seem to see it already suggested....

const d = new Date();
const day = d.getDate();
const goBack = 3;
for (let i = 0; i < goBack; i++) d.setDate(0);
d.setDate(day);

This will give you the date of today's date 3 months ago as .setDate(0) sets the date to the last day of last month irrespective of how many days a month contains. day is used to restore today's date value.

Solution 12 - Javascript

This is the Smallest and easiest code.

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

Declare variable which has current date. then just by using setMonth inbuilt function we can get 3 month back date.

Solution 13 - Javascript

d.setMonth changed local time in browser try

 const calcDate = (m) => {
    let date = new Date();
    let day = date.getDate();
    let month = date.getMonth() + 1;
    let year = date.getFullYear();
    let days = 0;

    if (m > 0) {
      for (let i = 1; i < m; i++) {
        month += 1;
        if (month > 12) {
          year += 1;
          month = 1;
        }
        days += new Date(year, month, 0).getDate();
      }
    } else {
      for (let i = m; i < 0; i++) {
        month -= 1;
        if (month < 1) {
          year -= 1;
          month = 12;
        }
        days -= new Date(year, month, 0).getDate();
      }
    }

    const newTime = date.getTime() + 3600 * 24 * 1000 * days;
    return new Date(newTime);
  };

calcDate(3)//+3 month

Solution 14 - Javascript

var todayDate = new Date().toISOString().slice(0, 10);
var d = new Date(todayDate);
d.setMonth(d.getMonth() -3);

console.log(todayDate) console.log(d.toISOString().slice(0, 10));

Solution 15 - Javascript

Since "Feb 31th" is auto converted to "March 3" or "March 2", as a month before "March 31th", which is quite counterintuitive, I decided to do it just like how I do it in my mind. Similar to @Don Kirkby 's answer, I also revise the date with the last day of the target month.

function nMonthsAgo(date, n) {
  // get the target year, month, date
  const y = date.getFullYear() - Math.trunc(n / 12) 
  const m = date.getMonth() - n % 12
  let d = date.getDate()
  if (d > 27) {   // get a valid date
    const lastDateofMonth = new Date(y, m + 1, 0).getDate()
    d = Math.min(d, lastDateofMonth) 
  }
  return new Date(y, m, d) 
}

d = new Date('2022-03-31')
nMonthsAgo(d, 1).toLocaleDateString()

Finally, I love what @gilly3 said in his answer:

> If your requirements are more complicated than that, use some math and write some code. You are a developer! You don't have to install a library! You don't have to copy and paste from stackoverflow! You can develop the code yourself to do precisely what you need!

Solution 16 - Javascript

for (let monthOfYear = 0; monthOfYear < 12; monthOfYear++) {
  const maxDate = new Date();
  const minDate = new Date();
  const max = maxDate.setMonth(maxDate.getMonth() - (monthOfYear - 1), 0);
  const min = maxDate.setMonth(minDate.getMonth() - (monthOfYear), 1);

  console.log('max: ', new Date(max));
  console.log('min: ', new Date(min));
}

Solution 17 - Javascript

In my case I needed to substract 1 month to current date. The important part was the month number, so it doesn't care in which day of the current month you are at, I needed last month. This is my code:

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)

Substract 1 month to actual date it's not accurate, that's why in first place I set first day of the month (first day of any month always is first day) and in second place I substract 1 day, which always send you to last month. Hope to help you dude.

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)

Solution 18 - Javascript

 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");

Solution 19 - Javascript

Pass a JS Date object and an integer of how many months you want to add/subtract. monthsToAdd can be positive or negative. Returns a JS date object.

If your originalDateObject is March 31, and you pass -1 as monthsToAdd, then your output date will be February 28.

If you pass a large number of months, say 36, it will handle the year adjustment properly as well.

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

Solution 20 - Javascript

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>

Solution 21 - Javascript

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKeenUserView Question on Stackoverflow
Solution 1 - Javascriptgilly3View Answer on Stackoverflow
Solution 2 - JavascriptJan GrzView Answer on Stackoverflow
Solution 3 - Javascriptuser7394313View Answer on Stackoverflow
Solution 4 - JavascriptthinkdevcodeView Answer on Stackoverflow
Solution 5 - JavascriptHodeifa BaswelView Answer on Stackoverflow
Solution 6 - JavascriptNiet the Dark AbsolView Answer on Stackoverflow
Solution 7 - JavascriptAustinView Answer on Stackoverflow
Solution 8 - JavascriptDon KirkbyView Answer on Stackoverflow
Solution 9 - JavascriptpoojaView Answer on Stackoverflow
Solution 10 - JavascriptJamesDView Answer on Stackoverflow
Solution 11 - JavascriptSketchyView Answer on Stackoverflow
Solution 12 - JavascriptRohit GaidhaneView Answer on Stackoverflow
Solution 13 - JavascriptPatrykCodeView Answer on Stackoverflow
Solution 14 - JavascriptrahuldmView Answer on Stackoverflow
Solution 15 - JavascriptJoeyView Answer on Stackoverflow
Solution 16 - JavascriptLorkaView Answer on Stackoverflow
Solution 17 - Javascriptmiguel.angelView Answer on Stackoverflow
Solution 18 - JavascriptsanthoshView Answer on Stackoverflow
Solution 19 - JavascriptAdamView Answer on Stackoverflow
Solution 20 - JavascriptMohammad RahmanView Answer on Stackoverflow
Solution 21 - JavascriptsanthoshView Answer on Stackoverflow