119

I'm creating an application which lets you define events with a time frame. I want to automatically fill in the end date when the user selects or changes the start date. I can't quite figure out, however, how to get the difference between the two times, and then how to create a new end Date using that difference.

bdukes
  • 144,904
  • 22
  • 145
  • 175

16 Answers16

79

In JavaScript, dates can be transformed to the number of milliseconds since the epoc by calling the getTime() method or just using the date in a numeric expression.

So to get the difference, just subtract the two dates.

To create a new date based on the difference, just pass the number of milliseconds in the constructor.

var oldBegin = ...
var oldEnd = ...
var newBegin = ...

var newEnd = new Date(newBegin + oldEnd - oldBegin);

This should just work

EDIT: Fixed bug pointed by @bdukes

EDIT:

For an explanation of the behavior, oldBegin, oldEnd, and newBegin are Date instances. Calling operators + and - will trigger Javascript auto casting and will automatically call the valueOf() prototype method of those objects. It happens that the valueOf() method is implemented in the Date object as a call to getTime().

So basically: date.getTime() === date.valueOf() === (0 + date) === (+date)

Vincent Robert
  • 34,658
  • 14
  • 79
  • 118
  • What is the format required for .getTime() to work... For example - new Date('22-12-2012 00:00').getTime() will not work... Any ideas? – Jimmyt1988 Sep 18 '12 at 16:05
  • 1
    For date parsing in JS, I suggest you have a look to this question: http://stackoverflow.com/questions/1576753/parse-datetime-string-in-javascript – Vincent Robert Sep 19 '12 at 12:13
  • 9
    Are OldBegin, oldEnd, and NewBegin supposed to be `Date` objects? It's hard to tell what type of object they're supposed to be, since the variable declaration is omitted here. – Anderson Green Feb 24 '13 at 17:52
  • Also, there's a function that you can use to add or subtract dates in JavaScript: http://stackoverflow.com/a/1214753/975097 – Anderson Green Feb 25 '13 at 04:02
  • Be careful with adding numbers and days. See my answer below for explanation – Dan Apr 04 '13 at 12:24
27

JavaScript perfectly supports date difference out of the box

https://jsfiddle.net/b9chris/v5twbe3h/

var msMinute = 60*1000, 
    msDay = 60*60*24*1000,
    a = new Date(2012, 2, 12, 23, 59, 59),
    b = new Date("2013 march 12");


console.log(Math.floor((b - a) / msDay) + ' full days between'); // 364
console.log(Math.floor(((b - a) % msDay) / msMinute) + ' full minutes between'); // 0

Now some pitfalls. Try this:

console.log(a - 10); // 1331614798990
console.log(a + 10); // mixed string

So if you have risk of adding a number and Date, convert Date to number directly.

console.log(a.getTime() - 10); // 1331614798990
console.log(a.getTime() + 10); // 1331614799010

My fist example demonstrates the power of Date object but it actually appears to be a time bomb

Chris Moschini
  • 35,226
  • 19
  • 156
  • 186
Dan
  • 52,315
  • 38
  • 111
  • 148
  • Dan, I found your example the easiest to understand and follow. Thanks. – Melanie Jul 30 '14 at 18:52
  • 5
    The "pitfalls" are actually defaults based on the language specification. The subtraction operator `-` coerces the arguments to number, so the Date returns its time value. The `+` operator is overloaded, so might do addition, coercion to number or concatenation. Since Dates coerce to String in this case, `+` does concatenation. Confusion is not the fault of the Date object, but of overloading operators. – RobG Mar 22 '16 at 23:53
  • I added a jsfiddle and the results of the above lines of code in an edit. I also included a quick way to end up at NaN: b + 60000 - a – Chris Moschini Oct 15 '20 at 12:06
  • For those coming from search engines; avoid parsing strings by passing them to `new Date`, unless in specific formats (see [What are valid Date Time Strings in JavaScript?](https://stackoverflow.com/q/51715259/215552)). – Heretic Monkey Mar 28 '22 at 22:23
10

See JsFiddle DEMO

    var date1 = new Date();    
    var date2 = new Date("2025/07/30 21:59:00");
    //Customise date2 for your required future time

    showDiff();

function showDiff(date1, date2){

    var diff = (date2 - date1)/1000;
    diff = Math.abs(Math.floor(diff));

    var days = Math.floor(diff/(24*60*60));
    var leftSec = diff - days * 24*60*60;

    var hrs = Math.floor(leftSec/(60*60));
    var leftSec = leftSec - hrs * 60*60;

    var min = Math.floor(leftSec/(60));
    var leftSec = leftSec - min * 60;

    document.getElementById("showTime").innerHTML = "You have " + days + " days " + hrs + " hours " + min + " minutes and " + leftSec + " seconds before death.";

setTimeout(showDiff,1000);
}

for your HTML Code:

<div id="showTime"></div>
tika
  • 6,669
  • 2
  • 48
  • 81
  • Not all days are 24 hours long where daylight saving is observed. Using the built–in parser to parse an unsupported string format is not a good way to create a Date. – RobG Aug 30 '20 at 22:16
  • For those coming from search engines; avoid parsing strings by passing them to `new Date`, unless in specific formats (see [What are valid Date Time Strings in JavaScript?](https://stackoverflow.com/q/51715259/215552)). – Heretic Monkey Mar 28 '22 at 22:23
5

If you don't care about the time component, you can use .getDate() and .setDate() to just set the date part.

So to set your end date to 2 weeks after your start date, do something like this:

function GetEndDate(startDate)
{
    var endDate = new Date(startDate.getTime());
    endDate.setDate(endDate.getDate()+14);
    return endDate;
}

To return the difference (in days) between two dates, do this:

function GetDateDiff(startDate, endDate)
{
    return endDate.getDate() - startDate.getDate();
}

Finally, let's modify the first function so it can take the value returned by 2nd as a parameter:

function GetEndDate(startDate, days)
{
    var endDate = new Date(startDate.getTime());
    endDate.setDate(endDate.getDate() + days);
    return endDate;
}
Sid M
  • 4,340
  • 4
  • 28
  • 49
Joel Coehoorn
  • 380,066
  • 110
  • 546
  • 781
  • 33
    `GetDateDiff()` will break across month barriers. For example, 2011/04/26 and 2011/05/01 will return -25, but the offset should be 5 days. – nfm Apr 26 '11 at 01:40
  • var ds = new Date(2014, 0, 31, 0, 0, 0, 0); var de = new Date(2014, 2, 31, 0, 0, 0, 0); GetDateDiff(ds,de) return 0 – Noor Apr 22 '16 at 10:22
4

Thanks @Vincent Robert, I ended up using your basic example, though it's actually newBegin + oldEnd - oldBegin. Here's the simplified end solution:

    // don't update end date if there's already an end date but not an old start date
    if (!oldEnd || oldBegin) {
        var selectedDateSpan = 1800000; // 30 minutes
        if (oldEnd) {
            selectedDateSpan = oldEnd - oldBegin;
        }

       newEnd = new Date(newBegin.getTime() + selectedDateSpan));
    }
Community
  • 1
  • 1
bdukes
  • 144,904
  • 22
  • 145
  • 175
  • 1
    It's good point to explain why you are sometimes using `getTime` and sometimes not – Dan Apr 04 '13 at 12:22
3

Depending on your needs, this function will calculate the difference between the 2 days, and return a result in days decimal.

// This one returns a signed decimal. The sign indicates past or future.

this.getDateDiff = function(date1, date2) {
    return (date1.getTime() - date2.getTime()) / (1000 * 60 * 60 * 24);
}

// This one always returns a positive decimal. (Suggested by Koen below)

this.getDateDiff = function(date1, date2) {
    return Math.abs((date1.getTime() - date2.getTime()) / (1000 * 60 * 60 * 24));
}
sparkyspider
  • 12,580
  • 10
  • 77
  • 124
  • 1
    Place it in a `Math.abs()` call, and you will always get a positive decimal. – Koen. May 16 '12 at 14:26
  • 1
    Nice suggestion Koen. That gives people 2 options: just the true date diff as you suggested, or a datediff with the sign indicating if the difference is in the past or future. :) – sparkyspider May 18 '12 at 10:55
  • Please note that in JavaScript you can also add/substract a number in milliseconds to `date.getTime()` to get time in future/past. `var nextMinute = new Date( someDate.getTime() + 60 * 1000 ); – Dan Apr 04 '13 at 12:30
  • This is a typo? "between the 2 days". Probably between 2 dates. – tomazahlin Aug 16 '16 at 12:13
2

If using moment.js, there is a simpler solution, which will give you the difference in days in one single line of code.

moment(endDate).diff(moment(beginDate), 'days');

Additional details can be found in the moment.js page

Cheers, Miguel

Miguel Guardo
  • 763
  • 1
  • 6
  • 17
1
function compare()
{
  var end_actual_time    = $('#date3').val();

  start_actual_time = new Date();
  end_actual_time = new Date(end_actual_time);

  var diff = end_actual_time-start_actual_time;

  var diffSeconds = diff/1000;
  var HH = Math.floor(diffSeconds/3600);
  var MM = Math.floor(diffSeconds%3600)/60;

  var formatted = ((HH < 10)?("0" + HH):HH) + ":" + ((MM < 10)?("0" + MM):MM)
  getTime(diffSeconds);
}
function getTime(seconds) {
  var days = Math.floor(leftover / 86400);

  //how many seconds are left
  leftover = leftover - (days * 86400);

  //how many full hours fits in the amount of leftover seconds
  var hours = Math.floor(leftover / 3600);

  //how many seconds are left
  leftover = leftover - (hours * 3600);

  //how many minutes fits in the amount of leftover seconds
  var minutes = leftover / 60;

  //how many seconds are left
  //leftover = leftover - (minutes * 60);
  alert(days + ':' + hours + ':' + minutes);
}
Phil Bozak
  • 2,765
  • 1
  • 18
  • 27
dheerendra
  • 527
  • 6
  • 8
1

alternative modificitaion extended code..

http://jsfiddle.net/vvGPQ/48/

showDiff();

function showDiff(){
var date1 = new Date("2013/01/18 06:59:00");   
var date2 = new Date();
//Customise date2 for your required future time

var diff = (date2 - date1)/1000;
var diff = Math.abs(Math.floor(diff));

var years = Math.floor(diff/(365*24*60*60));
var leftSec = diff - years * 365*24*60*60;

var month = Math.floor(leftSec/((365/12)*24*60*60));
var leftSec = leftSec - month * (365/12)*24*60*60;    

var days = Math.floor(leftSec/(24*60*60));
var leftSec = leftSec - days * 24*60*60;

var hrs = Math.floor(leftSec/(60*60));
var leftSec = leftSec - hrs * 60*60;

var min = Math.floor(leftSec/(60));
var leftSec = leftSec - min * 60;




document.getElementById("showTime").innerHTML = "You have " + years + " years "+ month + " month " + days + " days " + hrs + " hours " + min + " minutes and " + leftSec + " seconds the life time has passed.";

setTimeout(showDiff,1000);
}
NovaYear
  • 157
  • 1
  • 2
  • 13
  • Please add further clarification to your answer and use better English. – Nic May 12 '15 at 14:53
  • This solution is wrong because you use 365 days, neglecting leap years. – Serhii Holinei Mar 03 '17 at 19:04
  • For those coming from search engines; avoid parsing strings by passing them to `new Date`, unless in specific formats (see [What are valid Date Time Strings in JavaScript?](https://stackoverflow.com/q/51715259/215552)). – Heretic Monkey Mar 28 '22 at 22:24
1

Below code will return the days left from today to futures date.

Dependencies: jQuery and MomentJs.

var getDaysLeft = function (date) {
  var today = new Date();
  var daysLeftInMilliSec = Math.abs(new Date(moment(today).format('YYYY-MM-DD')) - new Date(date));
  var daysLeft = daysLeftInMilliSec / (1000 * 60 * 60 * 24);   
  return daysLeft;
};

getDaysLeft('YYYY-MM-DD');
StaceyGirl
  • 7,242
  • 12
  • 35
  • 64
Vin S
  • 145
  • 1
  • 4
0

this code fills the duration of study years when you input the start date and end date(qualify accured date) of study and check if the duration less than a year if yes the alert a message take in mind there are three input elements the first txtFromQualifDate and second txtQualifDate and third txtStudyYears

it will show result of number of years with fraction

function getStudyYears()
    {
        if(document.getElementById('txtFromQualifDate').value != '' && document.getElementById('txtQualifDate').value != '')
        {
            var d1 = document.getElementById('txtFromQualifDate').value;

            var d2 = document.getElementById('txtQualifDate').value;

            var one_day=1000*60*60*24;

            var x = d1.split("/");
            var y = d2.split("/");

            var date1=new Date(x[2],(x[1]-1),x[0]);

            var date2=new Date(y[2],(y[1]-1),y[0])

            var dDays = (date2.getTime()-date1.getTime())/one_day;

            if(dDays < 365)
            {
                alert("the date between start study and graduate must not be less than a year !");

                document.getElementById('txtQualifDate').value = "";
                document.getElementById('txtStudyYears').value = "";

                return ;
            }

            var dMonths = Math.ceil(dDays / 30);

            var dYears = Math.floor(dMonths /12) + "." + dMonths % 12;

            document.getElementById('txtStudyYears').value = dYears;
        }
    }
Alexander Elgin
  • 6,326
  • 4
  • 35
  • 48
shareef
  • 8,594
  • 13
  • 57
  • 86
  • 1
    Never ever parse date strings to find year because string appearence (esp. separators) differs among browsers. Use `getFullYear` which was designed for that. ------- See datejs library on googlecode which possibly supports most corner cases – Dan Apr 04 '13 at 12:06
  • thanks for advice @Dan but it worked and tested for me on real goverment project (different browsers) is it that weak programming practive ? :) – shareef Apr 04 '13 at 13:10
0
<html>
<head>
<script>
function dayDiff()
{
     var start = document.getElementById("datepicker").value;
     var end= document.getElementById("date_picker").value;
     var oneDay = 24*60*60*1000; 
     var firstDate = new Date(start);
     var secondDate = new Date(end);    
     var diffDays = Math.round(Math.abs((firstDate.getTime() - secondDate.getTime())/(oneDay)));
    document.getElementById("leave").value =diffDays ;
 }
</script>
</head>
<body>
<input type="text" name="datepicker"value=""/>
<input type="text" name="date_picker" onclick="function dayDiff()" value=""/>
<input type="text" name="leave" value=""/>
</body>
</html>
0

If you use Date objects and then use the getTime() function for both dates it will give you their respective times since Jan 1, 1970 in a number value. You can then get the difference between these numbers.

If that doesn't help you out, check out the complete documentation: http://www.w3schools.com/jsref/jsref_obj_date.asp

Alexander Elgin
  • 6,326
  • 4
  • 35
  • 48
Aaron
  • 22,900
  • 10
  • 46
  • 48
0
var getDaysLeft = function (date1, date2) {
   var daysDiffInMilliSec = Math.abs(new Date(date1) - new Date(date2));
   var daysLeft = daysDiffInMilliSec / (1000 * 60 * 60 * 24);   
   return daysLeft;
};
var date1='2018-05-18';
var date2='2018-05-25';
var dateDiff = getDaysLeft(date1, date2);
console.log(dateDiff);
Vin S
  • 145
  • 1
  • 4
-1

THIS IS WHAT I DID ON MY SYSTEM.

var startTime=("08:00:00").split(":");
var endTime=("16:00:00").split(":");
var HoursInMinutes=((parseInt(endTime[0])*60)+parseInt(endTime[1]))-((parseInt(startTime[0])*60)+parseInt(startTime[1]));
console.log(HoursInMinutes/60);
Sean Cortez
  • 129
  • 1
  • 2
  • 7
-1
function checkdate() {
    var indate = new Date()
    indate.setDate(dat)
    indate.setMonth(mon - 1)
    indate.setFullYear(year)

    var one_day = 1000 * 60 * 60 * 24
    var diff = Math.ceil((indate.getTime() - now.getTime()) / (one_day))
    var str = diff + " days are remaining.."
    document.getElementById('print').innerHTML = str.fontcolor('blue')
}
bdukes
  • 144,904
  • 22
  • 145
  • 175
hiren gamit
  • 2,015
  • 5
  • 25
  • 22