ChatGPT解决这个技术问题 Extra ChatGPT

How to add days to Date?

How to add days to current Date using JavaScript? Does JavaScript have a built in function like .NET's AddDay()?


D
Daniel A. White

You can create one with:-

Date.prototype.addDays = function(days) { var date = new Date(this.valueOf()); date.setDate(date.getDate() + days); return date; } var date = new Date(); console.log(date.addDays(5));

This takes care of automatically incrementing the month if necessary. For example:

8/31 + 1 day will become 9/1.

The problem with using setDate directly is that it's a mutator and that sort of thing is best avoided. ECMA saw fit to treat Date as a mutable class rather than an immutable structure.


Simplified: Date.prototype.addDays=function(d){return new Date(this.valueOf()+864E5*d);};
@Duncan Are you sure this is the same as the above? This one simply adds 24 hours, but one day is not always 24 hours. I guess the question is how to increment the date part by 1 day, without changing the time part.
864E5 for some reason I prefer to write 24*60*60 in my code :)
Guys, do not use method of adding 864E5 because this does not take daylight saving difference where days can be 23 or 25 hours.
For those of you worried about Daylight Savings -- Don't. These algorithms change the underlying date, not how the date is interpreted. DST is implemented in the getters and setters of the date -- the getters to subtract an hour in the summer, and the setter to add that hour back during the summer to normalize the time. But only when using an absolute hour -- relative hours don't need to be interpreted. This is why date math works. IMHO...
s
sparebytes

Correct Answer:

function addDays(date, days) {
  var result = new Date(date);
  result.setDate(result.getDate() + days);
  return result;
}

Incorrect Answer:

This answer sometimes provides the correct result but very often returns the wrong year and month. The only time this answer works is when the date that you are adding days to happens to have the current year and month.

// Don't do it this way!
function addDaysWRONG(date, days) {
  var result = new Date();
  result.setDate(date.getDate() + days);
  return result;
}

Proof / Example

Check this JsFiddle

// Correct function addDays(date, days) { var result = new Date(date); result.setDate(result.getDate() + days); return result; } // Bad Year/Month function addDaysWRONG(date, days) { var result = new Date(); result.setDate(date.getDate() + days); return result; } // Bad during DST function addDaysDstFail(date, days) { var dayms = (days * 24 * 60 * 60 * 1000); return new Date(date.getTime() + dayms); } // TEST function formatDate(date) { return (date.getMonth() + 1) + '/' + date.getDate() + '/' + date.getFullYear(); } $('tbody tr td:first-child').each(function () { var $in = $(this); var $out = $('').insertAfter($in).addClass("answer"); var $outFail = $('').insertAfter($out); var $outDstFail = $('').insertAfter($outFail); var date = new Date($in.text()); var correctDate = formatDate(addDays(date, 1)); var failDate = formatDate(addDaysWRONG(date, 1)); var failDstDate = formatDate(addDaysDstFail(date, 1)); $out.text(correctDate); $outFail.text(failDate); $outDstFail.text(failDstDate); $outFail.addClass(correctDate == failDate ? "right" : "wrong"); $outDstFail.addClass(correctDate == failDstDate ? "right" : "wrong"); }); body { font-size: 14px; } table { border-collapse:collapse; } table, td, th { border:1px solid black; } td { padding: 2px; } .wrong { color: red; } .right { color: green; } .answer { font-weight: bold; }

DST Dates
Input +1 Day +1 Day Fail +1 Day DST Fail
03/10/2013
11/03/2013
03/09/2014
11/02/2014
03/08/2015
11/01/2015
2013
Input +1 Day +1 Day Fail +1 Day DST Fail
01/01/2013
02/01/2013
03/01/2013
04/01/2013
05/01/2013
06/01/2013
07/01/2013
08/01/2013
09/01/2013
10/01/2013
11/01/2013
12/01/2013
2014
Input +1 Day +1 Day Fail +1 Day DST Fail
01/01/2014
02/01/2014
03/01/2014
04/01/2014
05/01/2014
06/01/2014
07/01/2014
08/01/2014
09/01/2014
10/01/2014
11/01/2014
12/01/2014
2015
Input +1 Day +1 Day Fail +1 Day DST Fail
01/01/2015
02/01/2015
03/01/2015
04/01/2015
05/01/2015
06/01/2015
07/01/2015
08/01/2015
09/01/2015
10/01/2015
11/01/2015
12/01/2015


@bzlm: Yes, I believe the note should read "this approach fails if the 'from' date is not in the same year or month as the current date". I still worry that users will glance over the answer and not read the warning since it doesn't stand out. Thanks.
I think, even if this work it is not correct. There is no such constructor for Date: var result = new Date(date);, see http://www.w3schools.com/js/js_dates.asp. Even if this usually work, sometimes can lead to wrong results because of conversion to string and vice versa. It should be var result = new Date(date.getTime());
@Marcin, I agree that new Date(date.getTime()); is better but I don't think there is any case where new Date(date) will give a wrong answer due to string conversion. If anyone can provide an example I'd like to see it. How crazy would it be for a date constructor to not read the string the same way it is formatted to by default. From what I understand, the user's local timezone and date format settings should have no affect on the correctness of this function.
@AnkitBalyan, See other answers. It may not work correctly due to Daylights Savings Time
@JimmyDillies, the difference is new Date(); vs new Date(date). The first creates with the current year, month, and day; and then changes the day. The second creates a date with the given year, month, day, and then changes the day.
J
Joel Coehoorn
var today = new Date();
var tomorrow = new Date();
tomorrow.setDate(today.getDate()+1);

Be careful, because this can be tricky. When setting tomorrow, it only works because its current value matches the year and month for today. However, setting to a date number like "32" normally will still work just fine to move it to the next month.


Yeah? But what is this? (ran on March 31st, 2010): today = new Date(); tomorrow = new Date(); tomorrow.setDate(today.getDate()+1); alert(tomorrow.getMonth()); Says "3". alert(tomorrow); is correct... Why???
@sims month is 0 indexed. Month 3 is April
Why the need to create 2 separate date objects? Why not simply use the same date object: var d = new Date(); d.setDate( d.getDate() + 1 );?
This approach doesn't work across years. If your starting date is from a few years ago, getDate() returns the day of that year. Then, calling setDate sets the day in the current year. So it is NOT a good general solution. @AnthonyWJones's answer actually works correctly.
@DrewNoakes—your assertion that it doesn't work across years is wrong. getDate returns the day in the month, not "day of that year". E.g. var d = new Date(2015,11,30);d.setDate(d.getDate() + 370) gives 3 Jan 2017 which crosses 2 years.
s
sbrbot

My simple solution is:

nextday=new Date(oldDate.getFullYear(),oldDate.getMonth(),oldDate.getDate()+1);

this solution does not have problem with daylight saving time. Also, one can add/sub any offset for years, months, days etc.

day=new Date(oldDate.getFullYear()-2,oldDate.getMonth()+22,oldDate.getDate()+61);

is correct code.


Note: this resets time to 00:00:00 (can be an issue or not)
Doesn't work on the last day of any month, as you say. Makes this unusable on 12 days of the year. Sounds like a nightmare to debug!!!
No Drew, it is usable for all days on year. You can put date offset bigger than 31 or month offset bigger than 12 and this function will recalculate it as day in next month or month in next year. So for example: nextday=new Date(oldDate.getFullYear(),oldDate.getMonth(),oldDate.getDate()+40); is perfectly well code.
there is getMonth()+22 - what you think will it work!?
I Agree, use this way. We just had a bug because of daylight saving time because we were using setDate.
J
Jason

These answers seem confusing to me, I prefer:

var ms = new Date().getTime() + 86400000;
var tomorrow = new Date(ms);

getTime() gives us milliseconds since 1970, and 86400000 is the number of milliseconds in a day. Hence, ms contains milliseconds for the desired date.

Using the millisecond constructor gives the desired date object.


This solution doesn't take daylight savings into account. So, for example, this will return the same date, 23 hours later: new Date(new Date('11/4/2012').getTime() + 86400000)
@NoahMiller The problem which you bring up could be a feature not a bug! Adding 24 hours per day is sometimes the right thing to do, with the goal of knowing the resulting time based on DST. The date that your example returns has a time value of 11pm on November 4th which is what 24 hours later is on that particular day. The original poster asked about datetime which would seem to indicate some desire for correct times of the day. This answer is correct if you are in the case when your goal is the time 24 hours later.
I agree Noah, var d2 = new Date(d1.valueOf() + 24 * 60 * 60 * 1000) does what it says, adds a full day worth of ticks to a date.
This is absolutely correct for some cases (for example for 1 day cookies) and a simpler solution than most of the others. I dont get why it has so many downvotes and so few upvotes :/
This answer is correct if (and only if) your date represents a UTC date/time or if you only want to add 24-hour days. Some other answers (AnthonyWJones's) are correct if (and only if) your date represents local time. The thing to understand is that a JavaScript Date represents an absolute moment in time, and they DO NOT have a time zone, so you must choose the correct method to use based on the time zone that you know (in your mind) the date represents.
H
Hasee Amarathunga

Here is the way that use to add days, months, and years for a particular date in Javascript.

// To add Days
var d = new Date();
d.setDate(d.getDate() + 5);

// To add Months
var m = new Date();
m.setMonth(m.getMonth() + 5);

// To add Years
var y = new Date();
y.setFullYear(y.getFullYear() + 5);

s
sufyan.shoaib

Try

var someDate = new Date();
var duration = 2; //In Days
someDate.setTime(someDate.getTime() +  (duration * 24 * 60 * 60 * 1000));

Using setDate() to add a date wont solve your problem, try adding some days to a Feb month, if you try to add new days to it, it wont result in what you expected.


No, this should not be marked as the correct answer since this solution assumes that every day has 24*60*60*1000 seconds but it does not (daylight saving)!
Any evidence about the 'Feb' problem with setDate()? Is it this: stackoverflow.com/questions/5497637/…
+1 This SHOULD be marked as the correct answer. I believe that "daylight saving" is about presentation and not about value, which is just the number of milliseconds. From value-point of view - day is CONST number of millisecs, while in terms of presentation it may vary.
@disfated—this is not the correct answer. The day going out of daylight saving has 25 hours, but this method only adds 24 so the date will be the same. Using 24hrs to represent a day works if UTC methods are used instead, but why bother when using setDate is more convenient? ;-)
x
xiº

Just spent ages trying to work out what the deal was with the year not adding when following the lead examples below.

If you want to just simply add n days to the date you have you are best to just go:

myDate.setDate(myDate.getDate() + n);

or the longwinded version

var theDate = new Date(2013, 11, 15);
var myNewDate = new Date(theDate);
myNewDate.setDate(myNewDate.getDate() + 30);
console.log(myNewDate);

This today/tomorrow stuff is confusing. By setting the current date into your new date variable you will mess up the year value. if you work from the original date you won't.


Reading all the answers around until I find this jewel here. Now that makes sense. Amazing that the today/tomorrow thing was copied in almost all the answers, when it does not make sense at all and it is not "for readibility and clarity" as the author says in the most upvoted answer -in the most upvoted comment-, it is confusing and a bad practice and wrong
A
Adam Cox

The simplest approach that I have implemented is to use Date() itself. `

const days = 15; 
// Date.now() gives the epoch date value (in milliseconds) of current date 
nextDate = new Date( Date.now() + days * 24 * 60 * 60 * 1000)

`


You should use NicoESIEA's answer if you care about DST (which you should)
This by far is the most elegant solution to the problem because it takes care of the fact that it handles the nasty situation of setting days beyond that of the month. You could literally right the function like...function addTime(years, month, day). If you want to go crazy with it you could add the hours, minutes, seconds and the milliseconds. I used to do it a lot in Unity for keeping track of the time in game because it used the Epoch method.
s
serge
int days = 1;
var newDate = new Date(Date.now() + days * 24*60*60*1000);

CodePen

var days = 2; var newDate = new Date(Date.now() + days * 24*60*60*1000); document.write('Today: '); document.write(new Date()); document.write('
New: '); document.write(newDate);


Upvote for not requiring an intermediate date variable.
this is the best answer because it doesn't have mutation
Not every day has 24h, it fails for DST and leap seconds.
R
Ruslan López

If you can, use moment.js. JavaScript doesn't have very good native date/time methods. The following is an example Moment's syntax:

var nextWeek = moment().add(7, 'days'); alert(nextWeek);

Reference: http://momentjs.com/docs/#/manipulating/add/


@kpull1 the asker did not restrict the solution domain by asking if a built-in solution exists.
Modern note: Moment.js is incredibly heavy to add for such a small purpose. It's several hundred KB, and isn't webpack-friendly out of the box.
Our preferred library is date-fns. Webpack-friendly, fast, and treats Dates as immutable.
@LukeWilliams never heard of date-fns until now. will check it out. thanks.
@JoshuaComeau If you download it from cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.3/moment.min.js, it takes up 53,248 bytes on disk. I imagine that's the whole ball o' wax, but I don't know. Anyway, whatever. It's not a big deal.
m
mark.nino.chua

I created these extensions last night: you can pass either positive or negative values;

example:

var someDate = new Date();
var expirationDate = someDate.addDays(10);
var previous = someDate.addDays(-5);


Date.prototype.addDays = function (num) {
    var value = this.valueOf();
    value += 86400000 * num;
    return new Date(value);
}

Date.prototype.addSeconds = function (num) {
    var value = this.valueOf();
    value += 1000 * num;
    return new Date(value);
}

Date.prototype.addMinutes = function (num) {
    var value = this.valueOf();
    value += 60000 * num;
    return new Date(value);
}

Date.prototype.addHours = function (num) {
    var value = this.valueOf();
    value += 3600000 * num;
    return new Date(value);
}

Date.prototype.addMonths = function (num) {
    var value = new Date(this.valueOf());

    var mo = this.getMonth();
    var yr = this.getYear();

    mo = (mo + num) % 12;
    if (0 > mo) {
        yr += (this.getMonth() + num - mo - 12) / 12;
        mo += 12;
    }
    else
        yr += ((this.getMonth() + num - mo) / 12);

    value.setMonth(mo);
    value.setYear(yr);
    return value;
}

The .addDays() method does not work for dates that cross daylight saving time boundaries.
This is one of the better answers here because you (correctly) use the number of millis since the epoc to represent dates/times, and add amounts of millis for adjustments... Why then did you not keep this up for "addMonths"!? And why no add year? Did you get bored?
Other than months, time periods can be represented by static numbers. But months can be four different lengths. Also, any time period length from Days and higher may have variable length at DST, so you can't use time-based addition anymore without another level of complexity. I added the addYears(), and I fixed addMonths().
s
sdgfsdh

A solution designed for the pipeline operator:

const addDays = days => date => {
  const result = new Date(date);

  result.setDate(result.getDate() + days);

  return result;
};

Usage:

// Without the pipeline operator...
addDays(7)(new Date());

// And with the pipeline operator...
new Date() |> addDays(7);

If you need more functionality, I suggest looking into the date-fns library.


N
NicoESIEA

the simplest answer is, assuming the need is to add 1 day to the current date:

var currentDate = new Date();
var numberOfDayToAdd = 1;
currentDate.setDate(currentDate.getDate() + numberOfDayToAdd );

To explain to you, line by line, what this code does:

Create the current date variable named currentDate. By default "new Date()" automatically assigns the current date to the variable. Create a variable to save the number of day(s) to add to the date (you can skip this variable and use directly the value in the third line) Change the value of Date (because Date is the number of the month's day saved in the object) by giving the same value + the number you want. The switch to the next month will be automatic


v
vaibhavmaster

Without using the second variable, you can replace 7 with your next x days:

let d=new Date(new Date().getTime() + (7 * 24 * 60 * 60 * 1000));

K
Kamil Kiełczewski

to substract 30 days use (24h=86400000ms)

new Date(+yourDate - 30 *86400000)

var yourDate=new Date(); var d = new Date(+yourDate - 30 *86400000) console.log(d)


When trying to calculate date time always remember that date time in based on milliseconds in computer science, (en.wikipedia.org/wiki/System_time#Retrieving_system_time) new Date(+yourDate + 30 * (24*60*60*1000))
R
Ruslan López

The simplest solution.

Date.prototype.addDays = function(days) { this.setDate(this.getDate() + parseInt(days)); return this; }; // and then call var newDate = new Date().addDays(2); //+2 days console.log(newDate); // or var newDate1 = new Date().addDays(-2); //-2 days console.log(newDate1);


I think this is the best solution. If we're extending the Date class, then it makes better sense that the Date instance is itself updated.
R
RemarkLima

Late to the party, but if you use jQuery then there's an excellent plugin called Moment:

http://momentjs.com/

var myDateOfNowPlusThreeDays = moment().add(3, "days").toDate();

http://momentjs.com/docs/#/manipulating/

And lots of other good stuff in there!

Edit: jQuery reference removed thanks to aikeru's comment


moment does not need jQuery :)
Even better in that case!!
Yes, after futzing around with Plain ol' JS for too long, I used Moment , and it just works(tm)!
Why would you want to use plugin when a few lines of JS will do?
@frenchie because, what starts as a few lines of JS and because clearly your application is manipulating days, dates and time related information, it'll soon be a few 1000 lines of JS, then you'll be asked to localise the app across 12 languages and timezones and you'd wished you had started out with something like moment ;)
R
Rohit.007

You can use JavaScript, no jQuery required:

var someDate = new Date();
var numberOfDaysToAdd = 6;
someDate.setDate(someDate.getDate() + numberOfDaysToAdd); 
Formatting to dd/mm/yyyy :

var dd = someDate.getDate();
var mm = someDate.getMonth() + 1;
var y = someDate.getFullYear();

var someFormattedDate = dd + '/'+ mm + '/'+ y;

Would like to vote for this because this answer gives the correct month as date.getMonth() ranges from 0 to 11 and needs to be incremented by 1 as mentioned in this solution.
P
Prashant Pimpale

As simple as this:

new Date((new Date()).getTime() + (60*60*24*1000));

While this does add UTC days, it uses local methods and doesn't allow for local days that aren't 24 hours long, which happens when the timezone offset changes (e.g. in and out of daylight saving).
O
Oli

Thanks Jason for your answer that works as expected, here is a mix from your code and the handy format of AnthonyWJones :

Date.prototype.addDays = function(days){
    var ms = new Date().getTime() + (86400000 * days);
    var added = new Date(ms);
    return added;
}

It does not take into account daylight saving when there's more or less than 86400000 seconds in a day and can result in logical error (program bug) in your code.
Sometimes that's needed. The eBay API has x-day auctions which are 24-hour based so your item will end at a different time than it goes up if DST status changes mid-auction. In that case you need to use this type of function to avoid logical errors.
T
Todd

Old I know, but sometimes I like this:

function addDays(days) {
    return new Date(Date.now() + 864e5 * days);
}

This one makes the most sense to me. It's simple, elegant and doesn't fall pray to issues moving over months/years.
Simplest answer presented. Building on this, the prototype 'addDays' would be the following: Date.prototype.addDays = function(days) {return new Date(this.getTime() + (864e5 * days));};
Not every day has 24h, it fails for DST and leap seconds.
r
ross

You can try:

var days = 50;

const d = new Date();

d.setDate(d.getDate() + days)

This should work well.


I upvoted this, but the true one liner is new Date( (new Date()).setDate((new Date()).getDate() + 1) )
V
Vahag Chakhoyan

No, javascript has no a built in function, but you can use a simple line of code

timeObject.setDate(timeObject.getDate() + countOfDays);

J
Joshua Comeau

I had issues with daylight savings time with the proposed solution.

By using getUTCDate / setUTCDate instead, I solved my issue.

// Curried, so that I can create helper functions like `add1Day`
const addDays = num => date => {
  // Make a working copy so we don't mutate the supplied date.
  const d = new Date(date);

  d.setUTCDate(d.getUTCDate() + num);

  return d;
}

S
Skatox

Why so complicated?

Let's assume you store the number of days to add in a variable called days_to_add.

Then this short one should do it:

calc_date = new Date(Date.now() +(days_to_add * 86400000));

With Date.now() you get the actual unix timestamp as milliseconds and then you add as many milliseconds as you want to add days to. One day is 24h60min60s*1000ms = 86400000 ms or 864E5.


This works! And is actually smart, and short. I tested to see, if you add 30 days or 45 days, and if it calculates correctly and skips the correct months, and seems to be fine. The way this is done is what I was looking for, and using the "out of the box" js date function is the way to go, not complicating it, just using what already exists! Thumbs up! Thanks!
M
Matteo Conta

Generic prototype with no variables, it applies on an existing Date value:

Date.prototype.addDays = function (days) {
    return new Date(this.valueOf() + days * 864e5);
}

C
Community

The mozilla docs for setDate() don't indicate that it will handle end of month scenarios. See https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date

setDate()

Sets the day of the month (1-31) for a specified date according to local time.

That is why I use setTime() when I need to add days.


I would link to the ECMAScript docs, but they are released in PDF ;(
Re "mozilla docs for setDate() don't indicate that it will handle end of month scenarios". The "docs" have been updated so now they do. ;-)
D
Duncan

I guess I'll give an answer as well: Personally, I like to attempt to avoid gratuitous variable declaration, method calls, and constructor calls, as they are all expensive on performance. (within reason, of course) I was going to leave this as just comment under the Answer given by @AnthonyWJones but thought better of it.

// Prototype usage...
Date.prototype.addDays = Date.prototype.addDays || function( days ) {
    return this.setTime( 864E5 * days + this.valueOf() ) && this;
};

// Namespace usage...
namespace.addDaysToDate = function( date, days ) {
    return date.setTime( 864E5 * days + date.valueOf() ) && date;
};

// Basic Function declaration...
function addDaysToDate( date, days ) {
    return date.setTime( 864E5 * days + date.valueOf() ) && date;
};

The above will respect DST. Meaning if you add a number of days that cross DST, the displayed time (hour) will change to reflect that. Example: Nov 2, 2014 02:00 was the end of DST.

var dt = new Date( 2014, 10, 1, 10, 30, 0 );
console.log( dt );                  // Sat Nov 01 2014 10:30:00
console.log( dt.addDays( 10 ) );    // Tue Nov 11 2014 09:30:00

If you're looking to retain the time across DST (so 10:30 will still be 10:30)...

// Prototype usage...
Date.prototype.addDays = Date.prototype.addDays || function( days ) {
    return this.setDate( this.getDate() + days ) && this;
};

// Namespace usage...
namespace.addDaysToDate = function( date, days ) {
    return date.setDate( date.getDate() + days ) && date;
};

// Basic Function declaration...
function addDaysToDate( date, days ) {
    return date.setDate( date.getDate() + days ) && date;
};

So, now you have...

var dt = new Date( 2014, 10, 1, 10, 30, 0 );
console.log( dt );                  // Sat Nov 01 2014 10:30:00
console.log( dt.addDays( 10 ) );    // Tue Nov 11 2014 10:30:00

A
Aldo

Short:

function addDays(date, number) {
    const newDate = new Date(date);
    return new Date(newDate.setDate(newDate.getDate() + number));
}

console.log({
    tomorrow: addDays(new Date(), 1)
});

Advance:


function addDays(date, number) {
    const newDate = new Date(date);
    return new Date(newDate.setDate(date.getDate() + number));
}

function addMonths(date, number) {
    const newDate = new Date(date);
    return new Date(newDate.setMonth(newDate.getMonth() + number));
}

function addYears(date, number) {
    const newDate = new Date(date);
    return new Date(newDate.setFullYear(newDate.getFullYear() + number));
}

function getNewDate(dateTime) {
    let date = new Date();
    let number = parseInt(dateTime.match(/\d+/)[0]);

    if (dateTime.indexOf('-') != -1)
        number = (- number);


    if (dateTime.indexOf('day') != -1)
        date = addDays(date, number);

    else if (dateTime.indexOf('month') != -1)
        date = addMonths(date, number);

    else if (dateTime.indexOf('year') != -1)
        date = addYears(date, number);


    return date;
}


console.log({
    tomorrow: getNewDate('+1day'),
    yesterday: getNewDate('-1day'),
    nextMonth: getNewDate('+1month'),
    nextYear: getNewDate('+1year'),
});

With fix provide by jperl


However, this will modify the date object you pass to your functions. If you do this addDays(today, 1), today will now be tomorrow. function addDays(date, number) { const newDate = new Date(date) return new Date(newDate.setDate(newDate.getDate() + number)); }