Search code examples
javascriptdateclockhour

Calculate difference between 2 dates considering Daylight Saving Time


Given a start date, and a number of days, I need to display the end date = start date + number of days.

So I did something like this:

var endDate=new Date(startDate.getTime()+ONE_DAY);

Everything works fine, except that for 25 and 26 October gives one day less.

Ex.:

2014-01-01 + 2 days = 2014-01-03

2014-10-25 + 2 days = 2014-10-26 (here is the case I need to treat).

This difference appear because of the clock going back 1 hour. Practically 2014-10-27 00:00:00 becomes 2014-10-26 23:00:00.

A simple solution would be to compute this at another hour (example 3 AM). But I want to just display a note when this happens.

For example, if user inputs 2014-10-25, I show a popup saying [something].

Now here is the real problem... I can't seem to find any algorithm that says when clocks goes back in year X.

Example... in 2014 the day is 26 October. In 2016 is 30 October (https://www.gov.uk/when-do-the-clocks-change). Why? This date looks random to be, but I don't think it is. So... when does clock go back/forward?

EDIT: All answers/comments are helpful related to how to fix the problem. But... I already passed that stage. Now I only have an itch about "how on earth are the days when clock is changed computed?".


Solution

  • To find the difference between two dates in whole days, create Date objects, subtract one from the other, then divide by the milliseconds in one day and round. The remainder will only be out by 1 hour for daylight saving so will round to the right value.

    You may also need a small function to convert strings to Dates:

    // Return Date given ISO date as yyyy-mm-dd
    function parseISODate(ds) {
      var d = ds.split(/\D/);
      return new Date(d[0], --d[1], d[2]);
    }
    

    Get the difference in days:

    function dateDiff(d0, d1) {
      return Math.round((d1 - d0)/8.64e7);
    }
    
    // 297
    console.log(dateDiff(parseISODate('2014-01-01'), parseISODate('2014-10-25')));
    

    If you want to add days to a date, do something like:

    // Add 2 days to 2014-10-25
    var d = new Date(2014, 9, 25);
    d.setDate(d.getDate() + 2);
    
    console.log(d);   // 2014-10-27
    

    The built–in Date object takes account of daylight saving (thought there are bugs in some browsers).