Fix for DevExpress DST problem

Replacement for DevExpress AddDays method which is buggy when it comes to DST.

by junto

HTML

<table id="container">
  <tr><th>DevExpress</th><th>Fixed</th></tr>
</table>

CSS

.error {
  color: #ff0000;
}

JavaScript

var dxDate = new Date();
//dxDate.setTime(1457215200000); // Sat Mar 26 2016 23:00:00 GMT+0100 (W. Europe Standard Time)
dxDate.setTime(1457308740000);  // Sat Mar 26 2016 23:00:00 GMT+0000 (GMT Standard Time)

var fixedDate = new Date();
//fixedDate.setTime(1457215200000); // Sat Mar 26 2016 23:00:00 GMT+0100 (W. Europe Standard Time)
fixedDate.setTime(1457308740000);  // Sat Mar 26 2016 23:00:00 GMT+0000 (GMT Standard Time)

var daysToAdd = 1;

for (i=0; i<30; i++)
{
  dxDate = addDays(dxDate, daysToAdd);
  fixedDate = addDaysFixed(fixedDate, daysToAdd);
  
  if (dxDate.getTime() != fixedDate.getTime())
  {
  	$("#container").append("<tr class=\"error\"><td>" + dxDate + "</td><td>" + fixedDate+ "</td></tr>");
  }
	else
  {
  	$("#container").append("<tr><td>" + dxDate + "</td><td>" + fixedDate+ "</td></tr>");
  }  
}

function addDays(date, count) {
   var newDate = cloneDate(date);
   newDate.setUTCDate(count + newDate.getUTCDate());
   _aspxFixTimezoneGap(date, newDate);
   return newDate;
}

function cloneDate(date) {
   var cloned = new Date();
   cloned.setTime(date.getTime());
   return cloned;
}

function addDaysFixed(startDate, dayCount) {
 var date = cloneDate(startDate);
 var dayDiff = 0;
 var hourInc = 3600000;
 if(dayCount < 0)
  hourInc = -1 * hourInc;
 dayCount = Math.abs(dayCount);
 while(true) {
  if(dayDiff == dayCount && startDate.getHours() == date.getHours())
   return date;
  if(dayDiff > dayCount) {
   date.setTime(-1 * hourInc + date.getTime());
   return date;
  }
  var day = date.getDate();
  date.setTime(hourInc + date.getTime());
  if(day != date.getDate())
   dayDiff++;
 }
 return date;
}

function _aspxFixTimezoneGap(oldDate, newDate) {
   var diff = newDate.getHours() - oldDate.getHours();
   if(diff == 0)
      return;
   var sign = (diff == 1 || diff == -23) ? -1 : 1;
   var trial = new Date(newDate.getTime() + sign * 3600000);
   if(sign > 0 || trial.getDate() == newDate.getDate())
      newDate.setTime(trial.getTime());
}