Get a date object (six months prior) from another date object
Asked Answered
L

5

27

How can I create a date object which is less than n number of months from another date object? I am looking for something like DateAdd().

Example:

var objCurrentDate = new Date();

Now using objCurrentDate, how can I create a Date object having a date which is six months older than today's date / objCurrentDate?

Logy answered 30/10, 2009 at 6:59 Comment(0)
G
61

You can implement very easily an "addMonths" function:

function addMonths(date, months) {
  date.setMonth(date.getMonth() + months);
  return date;
}


addMonths(new Date(), -6); // six months before now
// Thu Apr 30 2009 01:22:46 GMT-0600 

addMonths(new Date(), -12); // a year before now
// Thu Oct 30 2008 01:20:22 GMT-0600

EDIT: As reported by @Brien, there were several problems with the above approach. It wasn't handling correctly the dates where, for example, the original day in the input date is higher than the number of days in the target month.

Another thing I disliked is that the function was mutating the input Date object.

Here's a better implementation handling the edge cases of the end of months and this one doesn't cause any side-effects in the input date supplied:

const getDaysInMonth = (year, month) => new Date(year, month, 0).getDate()

const addMonths = (input, months) => {
  const date = new Date(input)
  date.setDate(1)
  date.setMonth(date.getMonth() + months)
  date.setDate(Math.min(input.getDate(), getDaysInMonth(date.getFullYear(), date.getMonth()+1)))
  return date
}

console.log(addMonths(new Date('2020-01-31T00:00:00'), -6))
// "2019-07-31T06:00:00.000Z"

console.log(addMonths(new Date('2020-01-31T00:00:00'), 1))
// "2020-02-29T06:00:00.000Z"

console.log(addMonths(new Date('2020-05-31T00:00:00'), -6))
// "2019-11-30T06:00:00.000Z"

console.log(addMonths(new Date('2020-02-29T00:00:00'), -12))
// "2019-02-28T06:00:00.000Z"
Geraldo answered 30/10, 2009 at 7:21 Comment(2)
Breaks on January 31. Returns invalid date June 31 as 6mos prior. See Charlie's answer below...Mixer
@BrienMalone, I have reviewed the original function I wrote back in 2009, check the new version. It handles the edge cases, and it avoids mutating the input date object argument. ThanksKnighthead
S
5

Create date object and pass the value of n, where n is number(add/sub) of month.

  var dateObj = new Date();
  var requiredDate= dateObj.setMonth(dateObj.getMonth() - n);
Shingly answered 4/1, 2017 at 11:1 Comment(0)
C
1
var oldDate:Date = new Date();
/*
 Check and adjust the date -
 At the least, make sure that the getDate() returns a 
 valid date for the calculated month and year.
 If it's not valid, change the date as per your needs.
 You might want to reset it to 1st day of the month/last day of the month
 or change the month and set it to 1st day of next month or whatever.
*/
if(oldDate.getMonth() < n)
    oldDate.setFullYear(oldDate.getFullYear() - 1);
oldDate.setMonth((oldDate.getMonth() + n) % 12);
Cardinal answered 30/10, 2009 at 7:12 Comment(0)
T
1

You have to be careful because dates have a lot of edge cases. For example, merely changing the month back by 6 doesn't account for the differing number of days in each month. For example, if you run a function like:

function addMonths(date, months) {
date.setMonth((date.getMonth() + months) % 12);
return date;
}

addMonths(new Date(2020, 7, 31), -6); //months are 0 based so 7 = August

The resulting date to return would be February 31st, 2020. You need to account for differences in the number of days in a month. Other answers have suggested this in various ways, by moving it to the first of the month, or the last of the month, or the first of the next month, etc. Another way to handle it is to keep the date if it is valid, or to move it to the end of the month if it overflows the month's regular dates. You could write this like:

function addMonths(date, months) {
  var month = (date.getMonth() + months) % 12;
  //create a new Date object that gets the last day of the desired month
  var last = new Date(date.getFullYear(), month + 1, 0);

  //compare dates and set appropriately
  if (date.getDate() <= last.getDate()) {
    date.setMonth(month);
  }

  else {
    date.setMonth(month, last.getDate());
  }

  return date;
}

This at least ensures that the selected day won't "overflow" the month that it is being moved to. Finding the last day of the month with the datePart = 0 method is documented here.

This function still leaves a lot to be desired, as it doesn't add years and you can't subtract more than a year (or you will run into a new issue with negatives being involved). However, fixing those and the other issues you may run into (namely timezones) will be left as an exercise for the reader.

Trinitrobenzene answered 1/10, 2019 at 13:47 Comment(0)
U
1

var d = new Date(0);
d.setUTCMilliseconds(Date.now()-15780000000);
console.log(d);
Unbated answered 18/2 at 22:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.