IWETHEY v. 0.3.0 | TODO
1,095 registered users | 0 active users | 0 LpH | Statistics
Login | Create New User
IWETHEY Banner

Welcome to IWETHEY!

New JavaScript DateAdd function?
Looking for a javascript function that emulates the DATEADD function of SQL. I wrote one that works for the most part, but the Month and Year adds have a slight problem. In T-SQL you'd have:
   SELECT DATEADD(mm, 1, '1/31/2004')\n   SELECT DATEADD(yy, 1, '2/29/2004')\nresults:\n   2004-02-29 00:00:00.000\n   2005-02-28 00:00:00.000

or in VBScript:
   <script language='vbscript'>\n      document.write(DateAdd("m"   , 1, "1/31/2004") & "<br>")\n      document.write(DateAdd("yyyy", 1, "2/29/2004") & "<br>")\n   </script>\nresults:\n   2/29/2004\n   2/28/2005

but my javascript function (as shown below) does not produce the same results:
   <script language='javascript'>\n      document.write(DateAdd("mm", 1, "1/31/2004") + "<br>");\n      document.write(DateAdd("yy", 1, "2/29/2004") + "<br>");\n   </script>\nresults:\n   Tue Mar 2 00:00:00 CST 2004\n   Tue Mar 1 00:00:00 CST 2005

Anyone know of an implementation of a JavaScript DateAdd that would be consistent with the T-SQL and VBScript?

\n<html>
<head>
<title>DateAdd</title>
<script language='javascript'>
function DateAdd(datepart, number, date) {
var d = new Date(date);
switch (datepart) {
// millisecond
case "ms":
return new Date(Date.parse(d) + (number));

// second
case "s":
case "ss":
return new Date(Date.parse(d) + (number*1000));

// minute
case "n":
case "mi":
return new Date(Date.parse(d) + (number*1000*60));

// hour
case "hh":
return new Date(Date.parse(d) + (number*1000*60*60));

// day
case "d":
case "dd":
return new Date(Date.parse(d) + (number*1000*60*60*24));

// week
case "wk":
case "ww":
return new Date(Date.parse(d) + (number*1000*60*60*24*7));

// month
case "m":
case "mm":
return new Date(
d.getFullYear(),
d.getMonth()+number,
d.getDate(),
d.getHours(),
d.getMinutes(),
d.getSeconds());

// quarter
case "q":
case "qq":
return new Date(
d.getFullYear(),
d.getMonth()+number*3,
d.getDate(),
d.getHours(),
d.getMinutes(),
d.getSeconds());

// year
case "yy":
case "yyyy":
return new Date(
d.getFullYear()+number,
d.getMonth(),
d.getDate(),
d.getHours(),
d.getMinutes(),
d.getSeconds());
}
}
</script>
</head>
<body>
<script language='javascript'>
document.write(DateAdd("mm", 1, "1/31/2004") + "<br>");
document.write(DateAdd("yy", 1, "2/29/2004") + "<br>");
</script>
</body>
</html>
New Problems.
There are several subtle things to watch out for when manipulating dates.

The first is that the month JavaScript's date type is 0-based, not 1-based. This might not be a problem in your code, as it deals with differences, though it might be a clue for you in debugging.

The second is that it's dangerous converting days or weeks to milli-seconds because the simply multiplication doesn't account for daylight-saving or leap-years. OTOH, I don't see any other way to do it...

Wade.

Is it enough to love
Is it enough to breathe
Somebody rip my heart out
And leave me here to bleed
 
Is it enough to die
Somebody save my life
I'd rather be Anything but Ordinary
Please

-- "Anything but Ordinary" by Avril Lavigne.

New Opportunities.
Hadn't even considered DST, since in reality I'm only dealing with whole dates (the time portions were just thrown in as an afterthought).

Biggest hassle I have is the differing lengths of months and leap years. I went ahead an kludged together a solution that works, but I'd druther it be someone else's problem. Haven't really thoroughly debugged it but here's what I came up with on short notice. (note: I know there's an issue with the mm and qq increments when they are more than 1 year in change - probably need a div function in there somewhere).
function isLeapYear(year) {\n   if (year % 4 == 0) {\n      if (year % 100 == 0) {\n         return (year % 400 == 0);\n      } else {\n         return (true);\n      }\n   }\n   return (false);\n}\n\nfunction daysInMonth(month, year) {\n   switch (month) {\n      case  0: return 31;  // january\n      case  1:             // february\n         if (isLeapYear(year)) {\n            return 29;\n         } else {\n            return 28;\n         }\n      case  2: return 31;  // march\n      case  3: return 30;  // april\n      case  4: return 31;  // may\n      case  5: return 30;  // june\n      case  6: return 31;  // july\n      case  7: return 31;  // august\n      case  8: return 30;  // september\n      case  9: return 31;  // october\n      case 10: return 30;  // november\n      case 11: return 31;  // december\n   }\n}\n\nfunction DateAdd(datepart, number, date) {\n   var d = new Date(date);\n   switch (datepart) {\n      // millisecond\n      case "ms":\n         return new Date(Date.parse(d) + (number));\n\n      // second\n      case "s":\n      case "ss":\n         return new Date(Date.parse(d) + (number*1000));\n\n      // minute\n      case "n":\n      case "mi":\n         return new Date(Date.parse(d) + (number*1000*60));\n\n      // hour\n      case "hh":\n         return new Date(Date.parse(d) + (number*1000*60*60));\n\n      // day\n      case "d":\n      case "dd":\n         return new Date(Date.parse(d) + (number*1000*60*60*24));\n\n      // week\n      case "wk":\n      case "ww":\n         return new Date(Date.parse(d) + (number*1000*60*60*24*7));\n\n      // month\n      case "m":\n      case "mm":\n         var i = 0;\n         var maxcurr = daysInMonth(d.getMonth(), d.getFullYear());\n         var mm = (d.getMonth() + number) % 12;\n         if (mm < 0) mm += 12;\n         var yy = d.getFullYear() + Math.floor((number + d.getMonth()) / 12);\n         var maxnext = daysInMonth(mm, yy);\n         if (maxnext < d.getDate()) {\n            i = (maxnext - d.getDate());\n         }\n         if (d.getDate() == maxcurr) {\n            i = (maxnext - maxcurr);\n         }\n         return new Date(\n            d.getFullYear(),\n            d.getMonth()+number,\n            d.getDate()+i,\n            d.getHours(),\n            d.getMinutes(),\n            d.getSeconds());\n\n      // quarter\n      case "q":\n      case "qq":\n         var i = 0;\n         var maxcurr = daysInMonth(d.getMonth(), d.getFullYear());\n         var mm = (d.getMonth() + number*3) % 12;\n         if (mm < 0) mm += 12;\n         var yy = d.getFullYear() + Math.floor((number*3 + d.getMonth()) / 12);\n         var maxnext = daysInMonth(mm, yy);\n         if (maxnext < d.getDate()) {\n            i = (maxnext - d.getDate());\n         }\n         if (d.getDate() == maxcurr) {\n            i = (maxnext - maxcurr);\n         }\n         return new Date(\n            d.getFullYear(),\n            d.getMonth()+number*3,\n            d.getDate()+i,\n            d.getHours(),\n            d.getMinutes(),\n            d.getSeconds());\n\n      // year\n      case "yy":\n      case "yyyy":\n         var i = 0;\n         if (d.getMonth() == 1) {\n            if (d.getDate() == 29) {\n               if (!isLeapYear(d.getFullYear() + number)) {\n                  i = -1;\n               }\n            }\n            if (d.getDate() == 28) {\n               if (!isLeapYear(d.getFullYear())) {\n                  if (isLeapYear(d.getFullYear() + number)) {\n                     i = 1;\n                  }\n               }\n            }\n         }\n         return new Date(\n            d.getFullYear()+number,\n            d.getMonth(),\n            d.getDate()+i,\n            d.getHours(),\n            d.getMinutes(),\n            d.getSeconds());\n   }\n}
New Looks good.
The only way to be sure is to come up with as many tests as you can think of and try them all out. That would be a lot of tests, I'm afraid.

Wade.

Is it enough to love
Is it enough to breathe
Somebody rip my heart out
And leave me here to bleed
 
Is it enough to die
Somebody save my life
I'd rather be Anything but Ordinary
Please

-- "Anything but Ordinary" by Avril Lavigne.

     JavaScript DateAdd function? - (ChrisR) - (3)
         Problems. - (static) - (2)
             Opportunities. - (ChrisR) - (1)
                 Looks good. - (static)

More aluminum-magnesium batons than you can shake a leg at.
119 ms