595

It amazes me that JavaScript's Date object does not implement an add function of any kind.

I simply want a function that can do this:

var now = Date.now();
var fourHoursLater = now.addHours(4);

function Date.prototype.addHours(h) {
  // How do I implement this?
}

I would simply like some pointers in a direction.

  • Do I need to do string parsing?

  • Can I use setTime?

  • How about milliseconds?

Like this:

new Date(milliseconds + 4*3600*1000 /* 4 hours in ms */)?

This seems really hackish though - and does it even work?

Michael M.
  • 10,486
  • 9
  • 18
  • 34
Jeff Meatball Yang
  • 37,839
  • 27
  • 91
  • 125

21 Answers21

654

JavaScript itself has terrible Date/Time API's. Nonetheless, you can do this in pure JavaScript:

Date.prototype.addHours = function(h) {
  this.setTime(this.getTime() + (h*60*60*1000));
  return this;
}
Mark Amery
  • 143,130
  • 81
  • 406
  • 459
Jason Harwig
  • 43,743
  • 5
  • 43
  • 44
410
Date.prototype.addHours= function(h){
    this.setHours(this.getHours()+h);
    return this;
}

Test:

alert(new Date().addHours(4));
kennebec
  • 102,654
  • 32
  • 106
  • 127
  • 28
    I don't think this works---test it on something with hour 23, for example? Jason Harwig's answer is what came to mind for me. – Domenic Oct 25 '10 at 16:08
  • 19
    It's bad practise to add things to an object prototype in Javascript, and Domenic is correct, this doesn't work. Jason Harwig's solution below is better. – Positonic Jul 06 '12 at 12:43
  • 20
    @Domenic This works fine with 23:00, tested inside the JavaScript console of Firefox 10, Chrome 21 and IE 8/9 Here the code I've used to test: `var date = new Date(2012, 10, 22, 23, 0, 1); date.toString(); // Thu Nov 22 2012 23:00:01 GMT+0100 (CET) date.setHours(date.getHours() + 1); date.toString(); // Fri Nov 23 2012 00:00:01 GMT+0100 (CET)` It also works fine with setMinutes() – tanguy_k Nov 22 '12 at 00:19
  • 5
    Ran into issues with this solution - Incrementing by 1 failed for me at DST changeover point (move clock forward an hour). – andrewb Oct 02 '15 at 02:09
  • 3
    Also got bitten by this -- I was looping through hours by using setHours(getHours-1): now, at first DST hour, this ends up being an infinite loop. So, check the result! – cfstras Mar 14 '16 at 12:57
  • Fails for me at the boundary where my locale (the United Kingdom) *exits* daylight savings time (though it works fine in the other direction, curiously). In Chrome, if I have `d=new Date('Sun Oct 27 2019 01:59:00 GMT+0100 (British Summer Time)')` and do `d.setHours(d.getHours() + 1)`, then `d` becomes *Sun Oct 27 2019 02:59:00 GMT+0000 (Greenwich Mean Time)*, which is actually 2 hours later, not 1 hour. – Mark Amery Sep 22 '19 at 16:58
  • Does not work when the next hour is the one that is changing from summer to vinter time and vice versa. `let date = new Date("2022-10-30T02:00:00"); console.log(date); date.setHours(date.getHours() + 1); console.log(date); ` This will yield: 2022-10-30T00:00:00.000Z 2022-10-30T02:00:00.000Z As you can see the UTC time is bumped two hours. – Christian Reinholdt Andersen Mar 25 '23 at 11:47
323

The below code will add 4 hours to a date (example, today's date):

var today = new Date();
today.setHours(today.getHours() + 4);

It will not cause an error if you try to add 4 to 23 (see the documentation):

If a parameter you specify is outside of the expected range, setHours() attempts to update the date information in the Date object accordingly

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
SuperNova
  • 25,512
  • 7
  • 93
  • 64
  • 1
    This doesnt seem to work when the hours is a decimal (not an integer) – gregmagdits Aug 16 '16 at 21:28
  • 16
    While using hour values >23 doesn't break this, it's nonetheless [broken at daylight savings boundaries](https://stackoverflow.com/questions/1050720/adding-hours-to-javascript-date-object#comment102500929_1051641). Given it's broken, there's no reason to use it; prefer `setTime` or `setUTCHour`. – Mark Amery Sep 22 '19 at 17:01
45

It is probably better to make the addHours method immutable by returning a copy of the Date object rather than mutating its parameter.

Date.prototype.addHours= function(h){
    var copiedDate = new Date(this.getTime());
    copiedDate.setHours(copiedDate.getHours()+h);
    return copiedDate;
}

This way you can chain a bunch of method calls without worrying about state.

Tahir Hassan
  • 5,715
  • 6
  • 45
  • 65
  • This function has same problems as stated out here http://stackoverflow.com/questions/1050720/adding-hours-to-javascript-date-object#comment4305695_1051641 It's not really about whether it works on certain browsers, but other places that use Javascript see this as an issue. combing your solution with this one http://stackoverflow.com/a/1050782/295535 appears to be the best solution – Ressu Dec 10 '12 at 06:55
  • 1
    You should consider changing the function name, as the word `add*` is commonly used to mutate the object itself. – mr5 May 11 '17 at 03:47
  • @mr5 - not sure about that, `add` is used in the .NET framework `DateTime` class a lot, and has the same meaning as the `+` (plus) in Math. – Tahir Hassan May 12 '17 at 08:43
  • 1
    `currentDate.addHours(1)` <- From my programming instinct, I'm expecting the `currentDate` value to change, but in your implementation, it would not. As to why I'm suggesting to rename or change its signature to something – mr5 May 12 '17 at 09:04
  • Normally you would assign the "changed" value to a new variable, e.g. `var futureDate = currentDate.addHours(1)`, this way you have access the to the original value of `currentDate` and you have a new variable for the new date. This is a modern pattern, part of the recent functional programming trend. – Tahir Hassan May 12 '17 at 14:56
  • 1
    @TahirHassan nothing to do with the technical details but on choosing the right word to use for function name. I still prefer the mutable version when the function is prefixed with `add` – mr5 May 26 '17 at 07:56
  • Modifying the prototype is not recommended. – Heretic Monkey Nov 15 '22 at 22:17
43

Get a date exactly two hours from now, in one line.

You need to pass milliseconds to new Date.

let expiryDate = new Date(new Date().setHours(new Date().getHours() + 2));

        or

let expiryDate2 = new Date(Date.now() + 2 * (60 * 60 * 1000) );

let nowDate = new Date();
let expiryDate = new Date(new Date().setHours(new Date().getHours() + 2));
let expiryDate2 = new Date(Date.now() + 2 * (60 * 60 * 1000) );

console.log('now', nowDate);
console.log('expiry', expiryDate);
console.log('expiry 2', expiryDate2);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
James Ikubi
  • 2,552
  • 25
  • 18
37

The version suggested by kennebec will fail when changing to or from DST, since it is the hour number that is set.

this.setUTCHours(this.getUTCHours()+h);

will add h hours to this independent of time system peculiarities.

Jason Harwig's method works as well.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
petter
  • 1,765
  • 18
  • 22
  • I implemented a variation of this that includes minutes, I wonder WHY `.setHours` wouldn't work, as DST only affects the hour anyways... – Eduardo06sp Mar 02 '22 at 06:21
  • @Eduardo06sp can you post the minute variation here? – Rajarshi Ghoshal Mar 10 '23 at 09:33
  • 1
    @RajarshiGhoshal `currentDate.setUTCHours(localToUTCHours + selectedOffsetHours, localToUTCMinutes + selectedOffsetMinutes)` this worked for my implementation, where I display a list of time zones, and there is a `` that shows the current time in the given time zone. Source code for more context because it's way too much to paste in here: https://github.com/Eduardo06sp/private-events/blob/main/app/javascript/src/user_registration_new.js – Eduardo06sp Mar 12 '23 at 01:07
  • Thank you so much. I did it like this - ``` item.createdAt.setUTCHours(item.createdAt.getUTCHours()+ 5 ); item.createdAt.setUTCMinutes(item.createdAt.getUTCMinutes()+ 30 ): ``` @Eduardo06sp – Rajarshi Ghoshal Mar 12 '23 at 05:52
  • @RajarshiGhoshal is there a particular reason you hard-coded the hours `5` and minutes `30`? That may work for anyone in your specific timezone, but not other people, since the offset would be different. I just wanted to give you that heads up! Good luck :} – Eduardo06sp Mar 12 '23 at 07:09
  • @Eduardo06sp no particular reason, it is just that our app is only in our local timezone. So it works for us. But I may consider using your solution for flexibility. Thanks again. – Rajarshi Ghoshal Mar 14 '23 at 05:13
26

You can use the Moment.js library.

var moment = require('moment');
foo = new moment(something).add(10, 'm').toDate();
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Cmag
  • 14,946
  • 25
  • 89
  • 140
9

I also think the original object should not be modified. So to save future manpower here's a combined solution based on Jason Harwig's and Tahir Hasan answers:

Date.prototype.addHours= function(h){
    var copiedDate = new Date();
    copiedDate.setTime(this.getTime() + (h*60*60*1000)); 
    return copiedDate;
}
Community
  • 1
  • 1
Edward Olamisan
  • 800
  • 1
  • 18
  • 28
9

If you would like to do it in a more functional way (immutability) I would return a new date object instead of modifying the existing and I wouldn't alter the prototype but create a standalone function. Here is the example:

//JS
function addHoursToDate(date, hours) {
  return new Date(new Date(date).setHours(date.getHours() + hours));
}

//TS
function addHoursToDate(date: Date, hours: number): Date {
  return new Date(new Date(date).setHours(date.getHours() + hours));
}

let myDate = new Date();

console.log(myDate)
console.log(addHoursToDate(myDate,2))
Patronaut
  • 1,019
  • 10
  • 14
  • 1
    Just a clarification: The `new Date(date)` is important because function `setHours()` would modify the original `date` object, thus having a side effect outside the scope of this function, which is against the principles of immutability. – Patronaut Dec 01 '20 at 11:26
4

There is an add in the Datejs library.

And here are the JavaScript date methods. kennebec wisely mentioned getHours() and setHours();

Nosredna
  • 83,000
  • 15
  • 95
  • 122
4

Check if it’s not already defined. Otherwise, define it in the Date prototype:

if (!Date.prototype.addHours) {
    Date.prototype.addHours = function(h) {
        this.setHours(this.getHours() + h);
        return this;
    };
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mikael Engver
  • 4,634
  • 4
  • 46
  • 53
3

This is an easy way to get an incremented or decremented data value.

const date = new Date()
const inc = 1000 * 60 * 60 // an hour
const dec = (1000 * 60 * 60) * -1 // an hour

const _date = new Date(date)
return new Date(_date.getTime() + inc)
return new Date(_date.getTime() + dec)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Henrique Van Klaveren
  • 1,502
  • 14
  • 24
2

Another way to handle this is to convert the date to unixtime (epoch), then add the equivalent in (milli)seconds, then convert it back. This way you can handle day and month transitions, like adding 4 hours to 21, which should result in the next day, 01:00.

SPRBRN
  • 2,406
  • 4
  • 35
  • 48
  • You're right - but you're also a couple of years late. [Jason Harwig's answer](https://stackoverflow.com/a/1050782/1709587) showed this method 2 years before you; this answer adds nothing new. – Mark Amery Sep 22 '19 at 17:15
1

SPRBRN is correct. In order to account for the beginning/end of the month and year, you need to convert to Epoch and back.

Here's how you do that:

var milliseconds = 0;          //amount of time from current date/time
var sec = 0;                   //(+): future
var min = 0;                   //(-): past
var hours = 2;
var days = 0;

var startDate = new Date();     //start date in local time (we'll use current time as an example)

var time = startDate.getTime(); //convert to milliseconds since epoch

//add time difference
var newTime = time + milliseconds + (1000*sec) + (1000*60*min) + (1000*60*60*hrs) + (1000*60*60*24*days);

var newDate = new Date(newTime); //convert back to date; in this example: 2 hours from right now

Or do it in one line (where variable names are the same as above:

var newDate =
    new Date(startDate.getTime() + millisecond +
        1000 * (sec + 60 * (min + 60 * (hours + 24 * days))));
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
JED
  • 1,538
  • 2
  • 19
  • 47
0

For a simple add/subtract hour/minute function in JavaScript, try this:

function getTime (addHour, addMin){
    addHour = (addHour ? addHour : 0);
    addMin = (addMin ? addMin : 0);
    var time = new Date(new Date().getTime());
    var AM = true;
    var ndble = 0;
    var hours, newHour, overHour, newMin, overMin;

    // Change form 24 to 12 hour clock
    if(time.getHours() >= 13){
        hours = time.getHours() - 12;
        AM = (hours>=12 ? true : false);
    }else{
        hours = time.getHours();
        AM = (hours>=12 ? false : true);
    }

    // Get the current minutes
    var minutes = time.getMinutes();

    // Set minute
    if((minutes + addMin) >= 60 || (minutes + addMin) < 0){
        overMin = (minutes + addMin) % 60;
        overHour = Math.floor((minutes + addMin - Math.abs(overMin))/60);
        if(overMin < 0){
            overMin = overMin + 60;
            overHour = overHour-Math.floor(overMin/60);
        }
        newMin = String((overMin<10 ? '0' : '') + overMin);
        addHour = addHour + overHour;
    }else{
        newMin = minutes + addMin;
        newMin = String((newMin<10 ? '0' : '') + newMin);
    }
    // Set hour
    if((hours + addHour >= 13) || (hours + addHour <= 0)){
        overHour = (hours + addHour) % 12;
        ndble = Math.floor(Math.abs((hours + addHour)/12));
        if(overHour <= 0){
            newHour = overHour + 12;
            if(overHour == 0){
                ndble++;
            }
        }else{
            if(overHour == 0){
                newHour = 12;
                ndble++;
            }else{
                ndble++;
                newHour = overHour;
            }
        }
        newHour = (newHour<10 ? '0' : '') + String(newHour);
        AM = ((ndble + 1) % 2 === 0) ? AM : !AM;
    }else{
        AM = (hours + addHour == 12 ? !AM : AM);
        newHour = String((Number(hours) + addHour < 10 ? '0': '') + (hours + addHour));
    }
    var am = (AM) ? 'AM' : 'PM';
    return new Array(newHour, newMin, am);
};

This can be used without parameters to get the current time:

getTime();

Or with parameters to get the time with the added minutes/hours:

getTime(1, 30); // Adds 1.5 hours to current time
getTime(2);    // Adds 2 hours to current time
getTime(0, 120); // Same as above

Even negative time works:

getTime(-1, -30); // Subtracts 1.5 hours from current time

This function returns an array of:

array([Hour], [Minute], [Meridian])
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
durkinza
  • 85
  • 1
  • 4
  • 5
    What advantage does this 56-line monster of a function have over the [two-line approach in the top-voted answer](https://stackoverflow.com/a/1050782/1709587)? -1 because there's huge extra complexity here for no benefit I can see. – Mark Amery Sep 22 '19 at 17:20
0

If you need it as a string, for example:

var defaultTime: new Date().getHours() + 1 + ":" + new Date().getMinutes();
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
khaled saleh
  • 470
  • 7
  • 18
0

I think this should do the trick

 var nextHour  = Date.now() + 1000 * 60 * 60;
 
 console.log(nextHour)
Ali Mousavi
  • 855
  • 7
  • 15
  • This makes `nextHour` a number value, not a `Date` value. Also, if you're going to use a snippet, use `console.log` to show the output. – Heretic Monkey Nov 15 '22 at 22:22
0

You can even format the date in desired format using the moment function after adding 2 hours.

var time = moment(new Date(new Date().setHours(new Date().getHours() + 2))).format("YYYY-MM-DD");
    
console.log(time);
Amar Kumar
  • 2,392
  • 2
  • 25
  • 33
  • 1
    This would require you to install the [Moment.js](https://momentjs.com/) library, so this solution only works if you are able and willing to install a 3rd-party library. – Adam Torma Feb 14 '23 at 10:45
0

I use this method to set a logout time for user if user do not provide a time. Users that log in before 9pm today are expected to log out on or before 10pm today while user that login any time greater than 9pm today must be logout latest 10pm next day

const loginDate = new Date();
const futureDate = new Date();
   
  const hour = loginDate.getHours();
  // 21 is added to ensure the time do not exceed 10pm the next day
  if(hour >= 21){
    remainingHourInTheDay = 24 - hour;
    let nextDay_10pm = remainingHourInTheDay + 21 ;
    const hoursInMillis = nextDay_10pm * 60 * 60 * 1000;
futureDate.setTime(futureDate.getTime() + hoursInMillis);
    console.log("Must Logout tomorrow at", futureDate)
  }
  else {
    todaysAlertAt_10pm = 21 - hour;
    const hoursInMillis = todaysAlertAt_10pm * 60 * 60 * 1000;
    futureDate.setTime(futureDate.getTime() + hoursInMillis);
    console.log("Must Logout today At", futureDate);
  }
console.log("Time now", new Date());
-1

The easiest way to do it is:

const myDate = new Date();

myDate.setHours(myDate.getHours() + 2);

It will add 2 hours to the current time.

function addHoursToDate(myDate, hours) {
  myDate.setHours(myDate.getHours() + hours);
}

const myDate = new Date();
console.log("Current Date: ", myDate);

addHoursToDate(myDate, 2)
console.log("Updated Date: ", myDate);
Qasim Rizvi
  • 99
  • 1
  • 9
-2

A little messy, but it works!

Given a date format like this: 2019-04-03T15:58

  //Get the start date.
  var start = $("#start_date").val();
  //Split the date and time.
  var startarray = start.split("T");
  var date = startarray[0];
  var time = startarray[1];

  //Split the hours and minutes.
  var timearray = time.split(":");

  var hour = timearray[0];
  var minute = timearray[1];
  //Add an hour to the hour.
  hour++;
  //$("#end_date").val = start;
  $("#end_date").val(""+date+"T"+hour+":"+minute+"");

Your output would be: 2019-04-03T16:58

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Carl Du Plessis
  • 325
  • 3
  • 6