833

How do I get the difference between 2 dates in full days (I don't want any fractions of a day)

var date1 = new Date('7/11/2010');
var date2 = new Date('12/12/2010');
var diffDays = date2.getDate() - date1.getDate(); 
alert(diffDays)

I tried the above but this did not work.

Brett DeWoody
  • 59,771
  • 29
  • 135
  • 184
chobo2
  • 83,322
  • 195
  • 530
  • 832
  • 46
    Just a side note: do not create Date objects with these kind of strings as input; it's non-standard and up to the browser how those are parsed. Use strings that can be parsed by [Date.parse](https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Date/parse) or, rather, use [three numeric values](http://ecma262-5.com/ELS5_Section_15.htm#Section_15.9.3.1) as the arguments to `new Date`, e.g. `new Date(2010, 11, 7);`. – Marcel Korpel Jul 11 '10 at 22:53
  • 4
    Side-note: Never trust the system time on client-side! It's wrong quite often, you might break your application. – Sliq Mar 15 '15 at 13:06
  • Also, try a small function at https://stackoverflow.com/a/53092438/3787376. – Edward Nov 03 '18 at 21:57
  • 6
    @Edward, you really call that a SMALL function? :) – Ihor Dec 19 '19 at 08:58
  • 1
    This is unsolvable. 1) 7/11/2010 could be July 11th, or November 7th. 2) What timezone? This could span the dateline. 3) with no time, the accuracy is +/- 1 day. 4) the result could be - when really it is positive (or vise versa) since there is no time/timezone – Andrew Sep 08 '21 at 15:44

5 Answers5

1248

Here is one way:

const date1 = new Date('7/13/2010');
const date2 = new Date('12/15/2010');
const diffTime = Math.abs(date2 - date1);
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); 
console.log(diffTime + " milliseconds");
console.log(diffDays + " days");

Observe that we need to enclose the date in quotes. The rest of the code gets the time difference in milliseconds and then divides to get the number of days. Date expects mm/dd/yyyy format.

Flimm
  • 136,138
  • 45
  • 251
  • 267
TNi
  • 16,070
  • 3
  • 22
  • 20
  • Ah the quotes was a typo. Still I get like 1 day with my way. – chobo2 Jul 11 '10 at 22:27
  • Whats (1000 * 3600 * 24) what is each of those (mins?seconds? hours?) – chobo2 Jul 11 '10 at 22:28
  • Another problem that what yours has and @volkan er does not seem to have is if date2 is less than date 1 yours will give a positive number instead of negative. – chobo2 Jul 11 '10 at 22:33
  • 12
    As volkan answered below, the 1000 * 3600 * 24 is the number of milliseconds per day. As for always returning a positive number, that was a feature :) Typically when one talks about the number of days between two dates, that number is positive. If direction matters, just remove the Math.abs(). – TNi Jul 11 '10 at 22:38
  • 2
    Likewise, you get 1 day with your method, because `getDate()` returns the day without regards to the month. Thus, you would get 12 - 11 = 1. – TNi Jul 11 '10 at 22:40
  • 5
    date already returned time do not need to call .getTime() – volkan er Jul 11 '10 at 22:56
  • 1
    @volkan er: Indeed, you're right. I can't ever remember things like that. – TNi Jul 11 '10 at 23:08
  • 12
    For this to work correctly with daylight saving, Math.round should replace Math.ceil. But I think Shyam's answer is the way to go. – Zemljoradnik Jun 24 '13 at 10:31
  • 1
    @Zemljoradnik , would you mind explaining why it won't work? getTime() returns UTC timestamps, so why is this not going to work? – Dalius Nov 29 '13 at 12:05
  • 1
    @Dalius the above doesn't work because the Date constructor creates the date in the local time zone. So, the UTC timestamps you get via getTime(), while being UTC values, reflect the DST adjusted value of the date. IOW, garbage in garbage out :-) – Shyam Habarakada Mar 04 '14 at 15:39
  • 1
    This is a very poor answer as parsing of date strings should never be left to the Date constructor. For most people in the world, 7/11/2010 represents 7 November, but most browsers treat it as 11 July. – RobG Apr 28 '14 at 12:09
  • between 7/11/2010 and 12/12/2010 155 day ?? – Alaeddine Jun 24 '14 at 03:44
  • 1
    I think it should be Math.floor instead of Math.ceil. Because Math.floor(120.12323) will return 120. And Math.ceil(120.1232144) will return 121. – gmail user Sep 02 '14 at 19:45
  • 10
    Won't work with a 23 hour 25 hour day in the calculated span. It would be helpful to consult a detailed treatment of UTC (Universal Coordinated Time) and "civil" time standards before devising a calculation such as this. A day is not a always 86,400 seconds, not even in UTC. However, ECMA standards state that it will not have the 58, 59, 61, or 62 second minutes that occur up to twice a year in UTC. You must not assume that offsets from epoch (00:00:00 hours 1 January 1970) in other languages and operating systems will be the same since some of them have 58, 59, 61, and 62 second minutes. – Jim Mar 08 '15 at 03:13
  • Warning! this "solution" always gives positive numbers, wich is wrong when you want the difference between a past Date and current Date by example. – Ninja Coding Jul 07 '17 at 16:38
  • 1
    I tried this with `03/11/2017 - 29/10/2017` and I got 6 days. `Math.ceil` isn't the right solution for all cases. I upvoted this answer prematurely. – nonzaprej Nov 15 '17 at 10:50
  • the result can be unexpected if the two days are not in the same GMT (I got an error when the timezone changed for some periods of the year) – Sérgio S. Filho Mar 02 '18 at 03:34
  • It's not working. I have tried the below dates, its return NaN. date1 = '01/01/2020' and date2 = '30/01/2021' – Mohanraj Periyannan May 21 '21 at 12:01
  • You could also do something like this: ```ts const firstDate = new Date(); const secondDate = new Date(); const difference = new Date(secondDate.getTime() - firstDate.getTime()) const differenceInSeconds = difference.getTime(); console.log(`${secondDate.getTime()} - ${firstDate.getTime()} = ${differenceInSeconds}`) ``` – zrilman Jun 17 '21 at 18:41
  • If the date1 points to yesterday 12 PM and date2 points to today 8AM, the function returns a wrong value. Sometime there could be 1 min time difference between 11:59 PM and 12:00 AM of tomorrow which should be considered 1 day. – Amir Gorji May 24 '22 at 09:28
  • The above date comparison differs when using React Native Hermes Engine. Please do not proceed with this way. – Rahul May 29 '22 at 20:57
  • won't work for typescript – Weijing Jay Lin Jan 19 '23 at 07:21
  • 1
    I guess it should be Math.floor ? Since the same day will become 1 – Jimmy lau Feb 25 '23 at 19:10
  • 1
    This answer is not correct. If you work with calendar which gives you a European format ('dd/mm/yyyy') then conversion will not work correctly. Follow @ShyamHabarakada advice. – George Mylonas Mar 02 '23 at 17:21
  • Why "ceil" not "floor"? "ceil" rounds up and gives 1 day more than in fact. Just found that I'm 3rd who corrects this, strange that author doesn't change the answer and everyone walks though the same pitfall here. – VirtualVAT Jul 05 '23 at 10:15
1001

A more correct solution

... since dates naturally have time-zone information, which can span regions with different day light savings adjustments

Previous answers to this question don't account for cases where the two dates in question span a daylight saving time (DST) change. The date on which the DST change happens will have a duration in milliseconds which is != 1000*60*60*24, so the typical calculation will fail.

You can work around this by first normalizing the two dates to UTC, and then calculating the difference between those two UTC dates.

Now, the solution can be written as,

// a and b are javascript Date objects
function dateDiffInDays(a, b) {
  const _MS_PER_DAY = 1000 * 60 * 60 * 24;
  // Discard the time and time-zone information.
  const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
  const utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());

  return Math.floor((utc2 - utc1) / _MS_PER_DAY);
}

// test it
const a = new Date("2017-01-01"),
    b = new Date("2017-07-25"),
    difference = dateDiffInDays(a, b);
    
console.log(difference + ' days')

This works because UTC time never observes DST. See Does UTC observe daylight saving time?

p.s. After discussing some of the comments on this answer, once you've understood the issues with javascript dates that span a DST boundary, there is likely more than just one way to solve it. What I provided above is a simple (and tested) solution. I'd be interested to know if there is a simple arithmetic/math based solution instead of having to instantiate the two new Date objects. That could potentially be faster.

João Pimentel Ferreira
  • 14,289
  • 10
  • 80
  • 109
Shyam Habarakada
  • 15,367
  • 3
  • 36
  • 47
  • 65
    this is the ONLY correct answer, i don't understand why other answer if accepted – obenjiro Apr 05 '13 at 08:26
  • 29
    probably because @chobo2 has not come back and looked at this question – Shyam Habarakada Apr 06 '13 at 20:47
  • 6
    @Ai_boy: While this is the most logically correct answer, there are no values for which it will fail to match the simpler `Math.round((b - a)/ _MS_PER_DAY, 0)`, so it's difficult to support "the ONLY correct answer". – Scott Sauyet Aug 21 '13 at 00:56
  • @ScottSauyet the issue we ran into was when a and b spanned across the day-light savings switch. When you say 'there are no values', have you included that as a scenario? – Shyam Habarakada Aug 21 '13 at 01:23
  • 1
    @ShyamHabarakada: That's a problem with a `Math.ceil` or `Math.floor` technique, but since daylight savings only adjusts by one hour from a 24-hour day, it will be swallowed up by `Math.round`. I haven't tested exhaustively, but I can see no case where the two would disagree. Can you? We're actually discussing this in [18347050](http://stackoverflow.com/questions/18347050/), which is how I ran across this old thread, and I brought up Daylight Savings there. – Scott Sauyet Aug 21 '13 at 01:30
  • 1
    Yes, rounding probably works as you describe, and assuming a and b are values in the same timezone, etc. but it fails in scenarios where a and b are datetime objects that aren't in the same time zone. For instance, try: `var a = new Date("Mon Sep 09 2013 17:46:44 GMT+0800 (PDT)");` and `b = new Date("Mon Sep 09 2013 17:46:44 GMT-0700 (PDT)")`, and then apply the Math.round technique to these dates. – Shyam Habarakada Sep 10 '13 at 00:49
  • 1
    +1 for removing the annoying `alert` – IcanDivideBy0 Oct 08 '13 at 14:06
  • How about providing return in hours? – Alex G Sep 21 '14 at 05:18
  • @Radio can you clarify what you mean? Maybe an example... – Shyam Habarakada Sep 24 '14 at 22:09
  • 1
    @RobG that's an interesting scenario, but I am not sure if I completely follow. Can you give an example? I use this code in an app, so if there is a bug, I'd really like to fix it :-) – Shyam Habarakada Oct 14 '14 at 07:27
  • Suppose that Javascript runs on **client side**, this answer is innecessarily complex. Please read [getTime()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime) and [UTC()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC). They both return the miliseconds from midnight January 1, 1970. – Mr. Duc Nguyen Dec 14 '14 at 22:41
  • 1
    @Mr.DucNguyen I am not sure what you are pointing out. In the code, `Date.UTC` is used to `construct` a new date object in the UTC time-zone. The `getTime()` function on an _already_initialized_ object return the milliseconds from UTC. Compare the difference between `d1 = new Date(2015,1,1)` and `d2 = new Date(Date.UTC(2015,1,1));` and you will understand what the code does. Thanks – Shyam Habarakada Feb 12 '15 at 02:24
  • @ShyamHabarakada I'm not sure why you were giving out the 2 dates in your comment. They are clearly different. Can you point out what is the different between: `t1 = (new Date(2015, 2, 1)).getTime()` and `t2 = Date.UTC(2015, 2, 1)` ? We are looking at these numbers to tell the different of 2 date objects. It's not the other way around, isn't it? – Mr. Duc Nguyen Feb 22 '15 at 23:16
  • 14
    Using UTC instead of a local time zone will correct the problems caused by 23 hour and 25 hour days in civil time systems. UTC also has 58, 59, 61, and 62 second minutes up to twice a year, so a day in UTC will not always have 86,400 seconds. However, ECMA standards state that JavaScript does not incorporate these adjustments so ignoring them when working purely in JavaScript works. However, other system do not ignore them and you must not assume offsets from the epoch moment (00:00:00 January 1, 1970) will always be the same between programming languages and operating systems. – Jim Mar 08 '15 at 03:03
  • This is strange but it seems there is no such method in momentJS. There is a `diff()` method, but it doesn't calculate the actual calendar difference, so e.g. `moment('2015-04-24T14:00:00.000Z').diff(moment('2015-04-24T11:00:00.000Z'), 'days')` will result to zero which is obviously not true in terms of whether this is the same date or not. – ivkremer Apr 24 '15 at 14:37
  • 1
    @Mr.DucNguyen I am not sure I understood your question. The examples you gave have the values `(new Date(2015, 2, 1)).getTime() => 1425196800000` and `Date.UTC(2015, 2, 1) => 1425168000000`. These dates, when converted to the same time-zone, comes out as `Sun Mar 01 2015 00:00:00 GMT-0800 (PST)` and `Sat Feb 28 2015 16:00:00 GMT-0800 (PST)` respectively. And the difference between those dates is 1 (or -1 if you reverse the comparison order). Does that make sense? – Shyam Habarakada Jun 16 '15 at 18:53
  • 1
    great Help. I am agree with @Ai_boy this answer need to accepted. Before I was using the answer which marked as a accepted but I am not getting result which I am looking for. I try accepted answer for date 06/15/2015 and 10/17/2015 the days difference I got is 122 days which is wrong when I try the your code snap result is 124 days and its correct . thanks for such a nice answer +1. – Simmant Jun 18 '15 at 11:43
  • @ShyamHabarakada—"local" date objects consider the system timezone setting when creating a date. The internal value is UTC, so if a place changes to DST at 02:00 and local dates are created for 01:00 and 03:00 for that day, the time difference (i.e. between the time values of the two dates) should be 1 hour, not 2 (since 02:00 instantly becomes 03:00). If you create dates using UTC for 01:00 and 03:00 the time difference will be 2 hours as there is no allowance for DST. But anyway, if the OP is only interested in whole days, rounding will fix DST variance since it's never more than 1 hour. – RobG Feb 20 '16 at 08:21
  • @RobG that is correct. Depending on what you mean by _rounding_ ... that is what the solution above does in a way. It takes any date and _rounds_ it to a UTC zoned date at 00:00:00 and then does the math to find the difference. OP says they want the difference in full days. Thinking about it more, I don't know if there is any other definition for _difference between two dates in days_ besides it being in full days. – Shyam Habarakada Feb 25 '16 at 20:04
  • @ShyamHabarakada—the OP didn't indicate any requirement for UTC, only the use of dates without either timezones or times, so using those values to create "local" date objects, subtracting, dividing by ms/day and rounding will produce exactly the same result as using UTC methods. The only difference is that the UTC version doesn't need rounding as it's never affected by DST if it's run on a system that's set to observe it. – RobG Feb 25 '16 at 21:01
  • @RobG lack of UTC requirements isn't the issue. The bug in the current accepted solution shows up if you are using it in a time zone that has day light savings changes and the dates that are being used as inputs span such DST change. HTH – Shyam Habarakada May 26 '16 at 09:47
  • @ShyamHabarakada—whatever. If only whole days are required, `Math.round((a-b)/8.64e7)` does the job. – RobG May 26 '16 at 14:15
  • Also see http://stackoverflow.com/questions/1968167/difference-between-dates-in-javascript/1968175#1968175 for a similar answer with **a function to get the maximum whole amount of a time unit in the value of a lower unit and the remainder lower unit for any amount of higher units (e.g. get whole minutes and whole remaining seconds and milliseconds)**. Note the answer doesn't cover cases where the two dates in question span a daylight saving time (DST) change. – Edward Sep 04 '16 at 20:53
  • @RobG hello again :-) I haven't followed your thinking to form a complete answer to the question in my head. Feel free to submit an edit or a new answer. Cheers, and happy new year. – Shyam Habarakada Dec 27 '16 at 22:06
  • This solution worked well for my needs in doing JS Rules in AEM 6.2 Adaptive Forms. I needed to return the difference in dates, in # of days, with positive and negative results. – Matt Swezey Feb 28 '17 at 20:26
  • var a = new Date(2017,9,25); var b = new Date(2017,10,6); for these dates i am getting 12 days diff but incase of, var a = new Date(2017,10,25); var b = new Date(2017,11,5); i am getting 11 days. This is wrong. i should get 13 days – Nalla Srinivas Oct 26 '17 at 08:55
  • @NallaSrinivas I tested your case and looks like the result is correct. Keep in mind when you create those dates, javascript by default creates a date-time object at 00:00:00 hours on the given day. So when you give it "2017-11-05" for instance, it's actually creating a date object that represents midnight the previous day, and when counting differences, it won't count the 05th. If you want to include the 5th, you should be doing `+1`. – Shyam Habarakada Jan 18 '18 at 16:58
  • This should be listed as the accepted answer. – Brian Smith Feb 27 '18 at 01:38
  • `Math.trunc()` should be used instead of `Math.floor()` to give correct results for negative numbers (i.e. when `utc1 > utc2`) – binaryfunt Sep 08 '18 at 17:05
  • But actually, is `Math.floor/trunc` needed at all? After discarding the time info, won't you always get an integer number of days returned? – binaryfunt Sep 08 '18 at 17:14
  • Is it possible to get the difference in seconds using this method? – Miguel Stevens Jul 04 '19 at 16:02
  • @Notflip depends on your definition of difference in seconds. If you want the number-od-days-difference multiplied by seconds in a day, yes sure you can leverage this method. But again, the answer depends on your exact definition... HTH – Shyam Habarakada Jul 21 '19 at 20:37
  • @ShyamHabarakada In your answer, the date is in Y-m-d format. Is this mandatory ? cos in other answers its in m-d-y format? – Abhinav Dec 07 '19 at 01:39
  • @Abhinav that shouldn't be an issue. Any format supported by the `new Date(...)` constructor should work. – Shyam Habarakada Feb 18 '20 at 21:55
  • Worked for me I agree @ShyamHabarakada should be answer for this question – sultanmyrza Sep 25 '20 at 10:29
  • To me, this answer seems wrong for the following reasons: 1. instead of converting to UTC, you're just taking the local values and pretending to be UTC. 2. If one is interested in the number of days between, it doesn't really matter if there's not exactly 86400s in between each day, especially if one of the days in between doesn't observe 86400s. – John Aug 05 '21 at 08:56
  • @John it depends on how you define "difference between dates". – Shyam Habarakada Aug 28 '21 at 04:39
  • 1
    @ShyamHabarakada - There's a bug in this answer, in that `a` and `b` are created by parsing strings in date-only format, which [by the ECMAScript spec](https://tc39.es/ecma262/#sec-date.parse) will be parsed as UTC. So when you ask for local-time year, month, and day, those are shifted and may not be the same as the values in the string depending on time zone. They *might* be shifted by the same amount, in which case you wouldn't notice. But one value could be shifted different than the other if on is in standard time and the other is in daylight saving time. – Matt Johnson-Pint Jul 19 '22 at 14:29
  • I think `getFullYear`, `getMonth`, `getDate` should be replaced with `getUTCFullYear` etc. – winwin Jan 14 '23 at 19:45
58
var date1 = new Date("7/11/2010");
var date2 = new Date("8/11/2010");
var diffDays = parseInt((date2 - date1) / (1000 * 60 * 60 * 24), 10); 

alert(diffDays )
volkan er
  • 996
  • 5
  • 6
  • 1
    date2 - date1 => milliseconds output (1000 * 60 * 60 * 24) => milisecond to day – volkan er Jul 11 '10 at 22:36
  • 10
    Isn't parseInt completely unnecessary? – Christian Jul 11 '10 at 23:02
  • to get full value in terms of number of days; request and will be subject to work-related... – volkan er Jul 11 '10 at 23:06
  • 3
    Christian: he wanted an integral number. parseInt is probably the worst way to do it. Math.round is the 'normal' way; it rounds instead of truncating. If truncating was desired, 'or'ing the expression with 0 would suffice: `(date2 - date1) / (1000 * 60 * 60 * 24) | 0` – Dagg Nabbit Jul 12 '10 at 00:05
  • 8
    Note that this solution isnt completely accurate as, in some cases i.e. 2015-04-06 minus 2015-04-04 gives an erroneous 1 day, all about parseInt() aproach. – ontananza Mar 24 '15 at 22:54
  • because some days are only 23 hours long. – Garr Godfrey Feb 02 '18 at 08:37
  • 1
    @ontananza `var date1 = new Date("2015-04-04"); var date2 = new Date("2015-04-06"); parseInt((date2 - date1) / (1000 * 60 * 60 * 24));` yields 2 for me – sdfsdf Jan 18 '19 at 20:18
  • @GarrGodfrey What planet do you live on? – sdfsdf Jan 18 '19 at 20:19
  • 1
    In areas that have daylight savings time, there is one day each year that is actually only 23 hours long. – Garr Godfrey Jan 22 '19 at 00:03
14

I tried lots of ways, and found that using datepicker was the best, but the date format causes problems with JavaScript....

So here's my answer and can be run out of the box.

<input type="text" id="startdate">
<input type="text" id="enddate">
<input type="text" id="days">

<script src="https://code.jquery.com/jquery-1.8.3.js"></script>
<script src="https://code.jquery.com/ui/1.10.0/jquery-ui.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/redmond/jquery-ui.css" />
<script>
$(document).ready(function() {

$( "#startdate,#enddate" ).datepicker({
changeMonth: true,
changeYear: true,
firstDay: 1,
dateFormat: 'dd/mm/yy',
})

$( "#startdate" ).datepicker({ dateFormat: 'dd-mm-yy' });
$( "#enddate" ).datepicker({ dateFormat: 'dd-mm-yy' });

$('#enddate').change(function() {
var start = $('#startdate').datepicker('getDate');
var end   = $('#enddate').datepicker('getDate');

if (start<end) {
var days   = (end - start)/1000/60/60/24;
$('#days').val(days);
}
else {
alert ("You cant come back before you have been!");
$('#startdate').val("");
$('#enddate').val("");
$('#days').val("");
}
}); //end change function
}); //end ready
</script>

a Fiddle can be seen here DEMO

trincot
  • 317,000
  • 35
  • 244
  • 286
Mikeys4u
  • 1,494
  • 18
  • 26
  • This is a similar problem to what I have the problem with this solution is that if the user clicks on the date2 datepicker first, then it fails. –  May 12 '18 at 06:30
6

This is the code to subtract one date from another. This example converts the dates to objects as the getTime() function won't work unless it's an Date object.

    var dat1 = document.getElementById('inputDate').value;
                var date1 = new Date(dat1)//converts string to date object
                alert(date1);
                var dat2 = document.getElementById('inputFinishDate').value;
                var date2 = new Date(dat2)
                alert(date2);

                var oneDay = 24 * 60 * 60 * 1000; // hours*minutes*seconds*milliseconds
                var diffDays = Math.abs((date1.getTime() - date2.getTime()) / (oneDay));
                alert(diffDays);
Pec1983
  • 346
  • 4
  • 8