544

I'm able to get the difference between two dates using MomentJs as follows:

moment(end.diff(startTime)).format("m[m] s[s]")

However, I also want to display the hour when applicable (only when >= 60 minutes have passed).

However, when I try to retrieve the duration hours using the following:

var duration = moment.duration(end.diff(startTime));
var hours = duration.hours();

it is returning the current hour and not the number of hours between the two dates.

How do I get the difference in hours between two Moments?

drew moore
  • 31,565
  • 17
  • 75
  • 112
Dani
  • 5,828
  • 2
  • 17
  • 21

17 Answers17

831

You were close. You just need to use the duration.asHours() method (see the docs).

var duration = moment.duration(end.diff(startTime));
var hours = duration.asHours();
GregL
  • 37,147
  • 8
  • 62
  • 67
  • 12
    Shouldn't it be `startTime.diff(end, 'hours', true);`? The duration.asHours(); would return 1 if it was 25 hours ago. – Daniel F Nov 05 '15 at 23:04
  • 44
    @DanielF If you are using MomentJS >= version 2.0.0, you could use `.diff()`, yes. Except it would be `end.diff(startTime, 'hours', true)` to get the number of hours as a positive number. However, your second point is not correct. `duration.hours()` would return 1 if it was 25 hours ago, but `duration.asHours()` would return 25. – GregL Nov 06 '15 at 04:11
  • 5
    @GregL I stand corrected https://jsfiddle.net/qxxr1Lyr/ I must have mistakenly used the `.hours()` method without noticing. – Daniel F Nov 06 '15 at 09:35
  • 5
    @zanderwar I understand your frustration, but this is a 5 year old question. Today such questions & answers wouldn't fly. – Jean-François Fabre Nov 02 '19 at 08:55
  • `05/12/2019 11:00 PM` and `06/12/2019 12:00 AM` is returning me 8761 while it should be 1 hour only – alamnaryab Dec 04 '19 at 18:56
  • @alamnaryab This is likely because you are not using a standard format for dates, so it is trying to interpret the dates in the current locale, which might be one of the crazy ones, like America, which is `MM/DD/YYYY`. I suggest you create your moment instances by specifying the format, using sth like: `var start = moment('05/12/2019 11:00 PM', 'DD/M/YYYY h:mm A');`. Then the code I posted will work as expected. – GregL Dec 10 '19 at 02:24
  • yes, I fixed it by changing format before diff, thank you – alamnaryab Dec 18 '19 at 17:26
  • 1
    Property 'diff' does not exist on type 'Date' – integrater May 11 '20 at 13:20
  • 2
    @integrater Is `end` in your code a Moment instance? Try wrapping it with `moment()` to convert it. `.diff()` is a MomentJS method only available on Moment objects, not native JS Date objects. – GregL May 11 '20 at 19:22
  • 1
    In my case i wanted duration in milliseconds. so i used `var mSec = duration.asMilliseconds();` thanks – Ish Mar 25 '21 at 16:27
319

Following code block shows how to calculate the difference in number of days between two dates using MomentJS.

var now = moment(new Date()); //todays date
var end = moment("2015-12-1"); // another date
var duration = moment.duration(now.diff(end));
var days = duration.asDays();
console.log(days)
M.A.Naseer
  • 343
  • 3
  • 9
selftaught91
  • 7,013
  • 3
  • 20
  • 26
  • 26
    This answer is clear enough and even more complete for me than the accepted answer above, where you do not know where 'end' and 'startTime' come from... Thanks a lot for your answer Raj! – Pierre Mar 16 '16 at 07:14
  • 5
    It's a little simpler to get now by `var now = moment();`. See http://momentjs.com/docs/#/parsing/now/ – rob3c May 11 '16 at 20:32
  • Hi, you can also use the moment.duration.days() in order to get the days (0 - 30). Here is the doc: https://momentjs.com/docs/#/durations/days/ – Raphael Escrig Mar 08 '22 at 09:44
221

Or you can do simply:

var a = moment('2016-06-06T21:03:55');//now
var b = moment('2016-05-06T20:03:55');

console.log(a.diff(b, 'minutes')) // 44700
console.log(a.diff(b, 'hours')) // 745
console.log(a.diff(b, 'days')) // 31
console.log(a.diff(b, 'weeks')) // 4

docs: here

Sebastián Lara
  • 5,355
  • 2
  • 28
  • 21
  • 17
    How can I show all hours, minutes and seconds together? Like HH:MM:SS ? – Faizan Saiyed Sep 13 '18 at 07:34
  • 13
    @FaizanSaiyed, I know it's late but, here's how to do - `var a = moment('2016-06-06T22:34:56'); var b = moment('2016-06-06T21:03:55'); var diff_s = a.diff(b, 'seconds'); console.log(moment.utc(moment.duration(diff_s, "seconds").asMilliseconds()).format("hh:mm:ss"))` – user632905 Jul 12 '20 at 15:35
  • 1
    @FaizanSaiyed, thank you for right solution. – Sanjay Kumar Jun 16 '21 at 05:41
43

There is a great moment method called fromNow() that will return the time from a specific time in nice human readable form, like this:

moment('2019-04-30T07:30:53.000Z').fromNow() // an hour ago || a day ago || 10 days ago

Or if you want that between two specific dates you can use:

var a = moment([2007, 0, 28]);
var b = moment([2007, 0, 29]);
a.from(b); // "a day ago"

Taken from the Docs:

Dryden Williams
  • 1,175
  • 14
  • 22
  • This is the best approach for me, as I don't need to calculate the hours/days/months/years-ago-strings myself and it is just one line! Thank you!! – krankuba Aug 06 '20 at 04:57
  • 1
    You can also pass a boolean to `from`/`fromNow` to remove the prefix from it. By default, it will return like `in 5 minutes`. Using the boolean (`a.from(b, true)`) you get only `5 minutes`. – Renan Souza May 31 '21 at 11:18
29

All you need to do is pass in hours as the second parameter to moments diff function.

var a = moment([21,30,00], "HH:mm:ss")
var b = moment([09,30,00], "HH:mm:ss")
a.diff(b, 'hours') // 12

Docs: https://momentjs.com/docs/#/displaying/difference/

Example:

const dateFormat = "YYYY-MM-DD HH:mm:ss";
// Get your start and end date/times
const rightNow = moment().format(dateFormat);
const thisTimeYesterday = moment().subtract(1, 'days').format(dateFormat);
// pass in hours as the second parameter to the diff function
const differenceInHours = moment(rightNow).diff(thisTimeYesterday, 'hours');

console.log(`${differenceInHours} hours have passed since this time yesterday`);
<script 
  src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js">
</script>
JSON C11
  • 11,272
  • 7
  • 78
  • 65
24

I know this is old, but here is a one liner solution:

const hourDiff = start.diff(end, "hours");

Where start and end are moment objects.

Enjoy!

Francois Nadeau
  • 7,023
  • 2
  • 49
  • 58
13

You just need to use the date.diff() method in moment.js

const now = moment.utc();
var end = moment("2021-09-13"); 
var days = now.diff(end, "days"); 
console.log(days)
<script src="https://momentjs.com/downloads/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
4

In my case, I wanted hours and minutes:

var duration = moment.duration(end.diff(startTime));
var hours = duration.hours(); //hours instead of asHours
var minutes = duration.minutes(); //minutes instead of asMinutes

For more info refer to the official docs.

Anil Singh
  • 4,293
  • 2
  • 24
  • 19
3
var __startTime = moment("2016-06-06T09:00").format();
var __endTime = moment("2016-06-06T21:00").format();

var __duration = moment.duration(moment(__endTime).diff(__startTime));
var __hours = __duration.asHours();
console.log(__hours);
AKHIL
  • 135
  • 3
2
 var start=moment(1541243900000);
 var end=moment(1541243942882);
 var duration = moment.duration(end.diff(startTime));
 var hours = duration.asHours();

As you can see, the start and end date needed to be moment objects for this method to work.

Richang Sharma
  • 442
  • 3
  • 6
  • 2
    While this code may answer the question, providing additional context regarding *how* and *why* it solves the problem would improve the answer's long-term value. – Alexander Nov 03 '18 at 15:40
2

Source: https://momentjs.com/docs/#/displaying/difference/

let startDate = "2022-08-14";

let endDate = "2022-08-20";

let startDateMoment = moment(startDate.split('-')); // ["2022", "08", "14"]

let endDateMoment = moment(endDate.split('-'));

console.log('Difference: ', endDateMoment.diff(startDateMoment, 'hours')); // 6
<script src="https://momentjs.com/downloads/moment.js"></script>
user3738870
  • 1,415
  • 2
  • 12
  • 24
Musab Gulfam
  • 126
  • 1
  • 7
1

I know this is already answered but in case you want something recursive and more generic and not relying on moment fromNow you could use this function I created. Of course you can change its logic to adjust it to your needs to also support years and seconds.

var createdAt = moment('2019-05-13T14:23:00.607Z');
var expiresAt = moment('2019-05-14T14:23:00.563Z');

// You can also add years in the beginning of the array or seconds in its end
const UNITS = ["months", "weeks", "days", "hours", "minutes"]
function getValidFor (createdAt, expiresAt, unit = 'months') {
    const validForUnit = expiresAt.diff(createdAt, unit);
    // you could adjust the if to your needs 
    if (validForUnit > 1 || unit === "minutes") {
    return [validForUnit, unit];
  }
  return getValidFor(createdAt, expiresAt, UNITS[UNITS.indexOf(unit) + 1]);
}
Mounir Dhahri
  • 204
  • 1
  • 7
1

As per the new Deprecation warning of Moment JSenter image description here

You need to pass Format of Start and end date Format along with values for example :

   let trackStartTime = "2020-12-29 09:59:19.07 +05:30";
   let trackEndTime = "2020-12-29 11:04:19.07 +05:30" || moment().format("YYYY-MM-DD HH:mm:ss.SS Z");
   let overallActivity = moment.duration(moment(trackEndTime, 'YYYY-MM-DD HH:mm:ss.SS Z').diff(moment(trackStartTime, 'YYYY-MM-DD HH:mm:ss.SS Z'))).asHours();
Mital Joshi
  • 1,132
  • 1
  • 11
  • 15
0

If you want total minutes between two dates in day wise than may below code will help full to you Start Date : 2018-05-04 02:08:05 , End Date : 2018-05-14 09:04:07...

function countDaysAndTimes(startDate,endDate){
return new Promise(function (resolve, reject) {
var dayObj = new Object;
var finalArray = new Array;

var datetime1 = moment(startDate);
var datetime2 = moment(endDate);
if(datetime1.format('D') != datetime2.format('D') || datetime1.format('M') != datetime2.format('M') ||  datetime1.format('YYYY') != datetime2.format('YYYY')){
  var onlyDate1 = startDate.split(" ");
  var onlyDate2 = endDate.split(" ");
  var totalDays = moment(onlyDate2[0]).diff(moment(onlyDate1[0]), 'days')

  // First Day Entry
  dayObj.startDate = startDate;
  dayObj.endDate = moment(onlyDate1[0]).add(1, 'day').format('YYYY-MM-DD')+" 00:00:00";
  dayObj.minutes = moment(dayObj.endDate).diff(moment(dayObj.startDate), 'minutes');
  finalArray.push(dayObj);

  // Between Days Entry
  var i = 1;
  if(totalDays > 1){
    for(i=1; i<totalDays; i++){
      var dayObj1 = new Object;
      dayObj1.startDate = moment(onlyDate1[0]).add(i, 'day').format('YYYY-MM-DD')+" 00:00:00";
      dayObj1.endDate = moment(onlyDate1[0]).add(i+1, 'day').format('YYYY-MM-DD')+" 00:00:00";
      dayObj1.minutes = moment(dayObj1.endDate).diff(moment(dayObj1.startDate), 'minutes');
      finalArray.push(dayObj1);
    }
  }

  // Last Day Entry
  var dayObj2 = new Object;
  dayObj2.startDate = moment(onlyDate1[0]).add(i, 'day').format('YYYY-MM-DD')+" 00:00:00";
  dayObj2.endDate = endDate ;
  dayObj2.minutes = moment(dayObj2.endDate).diff(moment(dayObj2.startDate), 'minutes');
  finalArray.push(dayObj2);

}
else{
  dayObj.startDate = startDate;
  dayObj.endDate = endDate;
  dayObj.minutes = datetime2.diff(datetime1, 'minutes');
  finalArray.push(dayObj);
}
console.log(JSON.stringify(finalArray));
// console.table(finalArray);
resolve(finalArray);
});
}

Output

 [
  {
  "startDate":"2018-05-04 02:08:05",
  "endDate":"2018-05-05 00:00:00",
  "minutes":1311
  },
  {
  "startDate":"2018-05-05 00:00:00",
  "endDate":"2018-05-06 00:00:00",
  "minutes":1440
  },
  {
  "startDate":"2018-05-06 00:00:00",
  "endDate":"2018-05-07 00:00:00",
  "minutes":1440
  },
  {
  "startDate":"2018-05-07 00:00:00",
  "endDate":"2018-05-08 00:00:00",
  "minutes":1440
  },
  {
  "startDate":"2018-05-08 00:00:00",
  "endDate":"2018-05-09 00:00:00",
  "minutes":1440
  },
  {
  "startDate":"2018-05-09 00:00:00",
  "endDate":"2018-05-10 00:00:00",
  "minutes":1440
  },
  {
  "startDate":"2018-05-10 00:00:00",
  "endDate":"2018-05-11 00:00:00",
  "minutes":1440
  },
  {
  "startDate":"2018-05-11 00:00:00",
  "endDate":"2018-05-12 00:00:00",
  "minutes":1440
  },
  {
  "startDate":"2018-05-12 00:00:00",
  "endDate":"2018-05-13 00:00:00",
  "minutes":1440
  },
  {
  "startDate":"2018-05-13 00:00:00",
  "endDate":"2018-05-14 00:00:00",
  "minutes":1440
  },
  {
  "startDate":"2018-05-14 00:00:00",
  "endDate":"2018-05-14 09:04:07",
  "minutes":544
  }
 ]
Renish Gotecha
  • 2,232
  • 22
  • 21
-1

Maybe could usefull for someone

          var ax = moment(
            new Date().toLocaleString(), // today/now is 09/12/2021 10:00:00
            "DD/MM/YYYY HH:mm:ss"
            ).diff(
              moment(
                "12/11/2022 13:43:11", // some time in future or past
                "DD/MM/YYYY HH:mm:ss"
              )
          );
          console.log('if today is in the future of the compared date then 
          result should be negative ==>', ax);
          // ax bigger than 0 zero means date in past. ms less than zero is in future
Adriel Werlich
  • 1,982
  • 5
  • 15
  • 30
-2
 calcDifferential(from, to) {
      const fromTime = this.$moment(from, 'hh:mm:ss')
      const toTime = this.$moment(to, 'hh:mm:ss')
      const ms = toTime.diff(fromTime)
      const d = this.$moment.duration(ms)
      const s = d.format()
      return s
    }
-14
            var timecompare = {
            tstr: "",
            get: function (current_time, startTime, endTime) {
                this.tstr = "";
                var s = current_time.split(":"), t1 = tm1.split(":"), t2 = tm2.split(":"), t1s = Number(t1[0]), t1d = Number(t1[1]), t2s = Number(t2[0]), t2d = Number(t2[1]);

                if (t1s < t2s) {
                    this.t(t1s, t2s);
                }

                if (t1s > t2s) {
                    this.t(t1s, 23);
                    this.t(0, t2s);
                }

                var saat_dk = Number(s[1]);

                if (s[0] == tm1.substring(0, 2) && saat_dk >= t1d)
                    return true;
                if (s[0] == tm2.substring(0, 2) && saat_dk <= t2d)
                    return true;
                if (this.tstr.indexOf(s[0]) != 1 && this.tstr.indexOf(s[0]) != -1 && !(this.tstr.indexOf(s[0]) == this.tstr.length - 2))
                    return true;

                return false;

            },
            t: function (ii, brk) {
                for (var i = 0; i <= 23; i++) {
                    if (i < ii)
                        continue;
                    var s = (i < 10) ? "0" + i : i + "";
                    this.tstr += "," + s;
                    if (brk == i)
                        break;
                }
            }};