
function ValidDate(y, m, d) { // m = 0..11 ; y m d integers, y!=0
  with (new Date(y, m, d, 6)) // 6 for Opera
    return (getMonth()==m && getDate()==d) /* was y, m */ }

function ReadISO8601date(Q) { var T // adaptable for other layouts
  if ((T = /^(\d+)([-\/])(\d\d)(\2)(\d\d)$/.exec(Q)) == null)
    { return -2 } // bad format
  for (var j=1; j<=5; j+=2) T[j] = +T[j] // some use needs numbers
  if (!ValidDate(T[1], T[3]-1, T[5])) { return -1 } // bad value
  return [ T[1], T[3], T[5] ] }

function DiffYA(S1, S2) {
    var D1 = ReadISO8601date(S1);
    if (D1 < 0) {
        return "Date 1 bad";
    }
    var D2 = ReadISO8601date(S2);
    if (D2 < 0) {
        return "Date 2 bad";
    }
    return D1[0] - D2[0] - (D1[1] * 100 + D1[2] < D2[1] * 100 + D2[2]);
}

function DiffYB(S1, S2) {
    var D1 = ReadISO8601date(S1);
    if (D1 < 0) {
        return "Date 1 bad";
    }
    var D2 = ReadISO8601date(S2);
    if (D2 < 0) {
        return "Date 2 bad";
    }
    var D = (D1[0] - D2[0]) * 10000 + (D1[1] - D2[1]) * 100 + (D1[2] - D2[2]);
    return Math.floor(D / 10000);
}

function DiffYC(S1, S2) {
    var D1 = ReadISO8601date(S1);
    if (D1 < 0) {
        return "Date 1 bad";
    }
    var D2 = ReadISO8601date(S2);
    if (D2 < 0) {
        return "Date 2 bad";
    }
    D1 = new Date(D1[0], D1[1], D1[2]);
    D2 = new Date(D2[0], D2[1], D2[2]);
    var age = D1.getFullYear() - D2.getFullYear();
    D2.setFullYear(D1.getFullYear());
    if (D2 > D1) {
        age--;
    }
    return age;
}

function DaysDiff(D1, D2) {
    return Math.round((D1 - D2) / 86400000);
}

function DiffDays(S1, S2) {
    var X = ReadISO8601date(S1);
    if (X < 0) {
        return "Date 1 bad";
    }
    var Y = ReadISO8601date(S2);
    if (Y < 0) {
        return "Date 2 bad";
    }
    var Dx = Date.UTC(X[0], X[1] - 1, X[2]);
    var Dy = Date.UTC(Y[0], Y[1] - 1, Y[2]);
    return (Dx - Dy) / 86400000;
}


