4

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?".

zozo
  • 8,230
  • 19
  • 79
  • 134
  • if you are not opposed to use a library i would highly recommend moment.js and moment timezone, it takes out a lot of the headaches when having to deal with these kind of situations (http://momentjs.com/) – Quince Oct 06 '14 at 07:37
  • Daylight saving is not based on a specific date, it's often 02:00 on the first Sunday in a particular month, changes frequently as places adopt it or stop using it, or just change the week it starts because it seems like a good idea. There is no consistency, though countries near the equator tend not to use it more than those near the poles. – RobG Oct 06 '14 at 08:16

2 Answers2

2

I prefer adding days this way:

    var startDate = //someDate;

    var endDate = new Date(startDate.getFullYear(),
               startDate.getMonth(),
               startDate.getDate()+1);

This way you don't have to worry about the days in the calendar.

This code add 1 day, if you want to add more, change the startDate.getDate()+1 for startDate.getDate()+NUMBER_OF_DAYS it works fine even if you are on the last day of month i.e. October 31th.

But maybe you can use @RobG solution which is more elegant than mine

Manjar
  • 3,159
  • 32
  • 44
  • No, .getMonth() gives you the month 0-index based, i mean from 0 to 11, but when you use new you must put the month with 1-12: http://www.w3schools.com/jsref/jsref_getmonth.asp – Manjar Oct 06 '14 at 08:04
  • I don't want to get cocky, but my link said literally: "Definition and Usage The getMonth() method returns the month (from 0 to 11) for the specified date, according to local time." which is what I said in the comment. In the ECMAScript refence says also: "Month Number Months are identified by an integer in the range 0 to 11, inclusive. The mapping MonthFromTime(t) from a time value t to a month number is defined by:" http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.4 – Manjar Oct 06 '14 at 08:45
  • I tested it, you are right! I did new Date(2000,1,1) and it instantiated the February 1st, not January 1st. A myth just died for me! Thank you for the info, and sorry for being stubborn! I'll go edit it. By the way I prefer your solution which is more elegant. – Manjar Oct 07 '14 at 07:13
2

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).

RobG
  • 142,382
  • 31
  • 172
  • 209