15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function arrayExists(array, x) {
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (var i = 0; i < array.length; i++) {
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (array[i] == x) return true;
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Date.prototype.formatDate = function (input,time) {
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // formatDate :
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // a PHP date like function, for formatting date strings
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // See: http://www.php.net/date
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // input : format string
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // time : epoch time (seconds, and optional)
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // if time is not passed, formatting is based on
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // the current "this" date object's set time.
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // supported:
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // a, A, B, d, D, F, g, G, h, H, i, j, l (lowercase L), L,
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // m, M, n, O, r, s, S, t, U, w, W, y, Y, z
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // unsupported:
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // I (capital i), T, Z
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var switches =    ["a", "A", "B", "d", "D", "F", "g", "G", "h", "H",
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                       "i", "j", "l", "L", "m", "M", "n", "O", "r", "s",
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                       "S", "t", "U", "w", "W", "y", "Y", "z"];
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var daysLong =    ["Sunday", "Monday", "Tuesday", "Wednesday",
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                       "Thursday", "Friday", "Saturday"];
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var daysShort =   ["Sun", "Mon", "Tue", "Wed",
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                       "Thu", "Fri", "Sat"];
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var monthsShort = ["Jan", "Feb", "Mar", "Apr",
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                       "May", "Jun", "Jul", "Aug", "Sep",
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                       "Oct", "Nov", "Dec"];
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var monthsLong =  ["January", "February", "March", "April",
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                       "May", "June", "July", "August", "September",
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                       "October", "November", "December"];
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var daysSuffix = ["st", "nd", "rd", "th", "th", "th", "th", // 1st - 7th
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                      "th", "th", "th", "th", "th", "th", "th", // 8th - 14th
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                      "th", "th", "th", "th", "th", "th", "st", // 15th - 21st
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                      "nd", "rd", "th", "th", "th", "th", "th", // 22nd - 28th
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                      "th", "th", "st"];                        // 29th - 31st
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function a() {
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Lowercase Ante meridiem and Post meridiem
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return self.getHours() > 11? "pm" : "am";
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function A() {
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Uppercase Ante meridiem and Post meridiem
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return self.getHours() > 11? "PM" : "AM";
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function B(){
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Swatch internet time. code simply grabbed from ppk,
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // since I was feeling lazy:
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // http://www.xs4all.nl/~ppk/js/beat.html
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var off = (self.getTimezoneOffset() + 60)*60;
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var theSeconds = (self.getHours() * 3600) +
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                         (self.getMinutes() * 60) +
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                          self.getSeconds() + off;
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var beat = Math.floor(theSeconds/86.4);
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (beat > 1000) beat -= 1000;
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (beat < 0) beat += 1000;
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if ((""+beat).length == 1) beat = "00"+beat;
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if ((""+beat).length == 2) beat = "0"+beat;
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return beat;
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function d() {
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Day of the month, 2 digits with leading zeros
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return new String(self.getDate()).length == 1?
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        "0"+self.getDate() : self.getDate();
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function D() {
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // A textual representation of a day, three letters
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return daysShort[self.getDay()];
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function F() {
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // A full textual representation of a month
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return monthsLong[self.getMonth()];
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function g() {
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // 12-hour format of an hour without leading zeros
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return self.getHours() > 12? self.getHours()-12 : self.getHours();
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function G() {
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // 24-hour format of an hour without leading zeros
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return self.getHours();
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function h() {
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // 12-hour format of an hour with leading zeros
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (self.getHours() > 12) {
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)          var s = new String(self.getHours()-12);
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)          return s.length == 1?
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)          "0"+ (self.getHours()-12) : self.getHours()-12;
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)          var s = new String(self.getHours());
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)          return s.length == 1?
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)          "0"+self.getHours() : self.getHours();
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function H() {
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // 24-hour format of an hour with leading zeros
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return new String(self.getHours()).length == 1?
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        "0"+self.getHours() : self.getHours();
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function i() {
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Minutes with leading zeros
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return new String(self.getMinutes()).length == 1?
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        "0"+self.getMinutes() : self.getMinutes();
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function j() {
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Day of the month without leading zeros
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return self.getDate();
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function l() {
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // A full textual representation of the day of the week
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return daysLong[self.getDay()];
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function L() {
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // leap year or not. 1 if leap year, 0 if not.
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // the logic should match iso's 8601 standard.
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var y_ = Y();
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            (y_ % 4 == 0 && y_ % 100 != 0) ||
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            (y_ % 4 == 0 && y_ % 100 == 0 && y_ % 400 == 0)
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ) {
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return 1;
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return 0;
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function m() {
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Numeric representation of a month, with leading zeros
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return self.getMonth() < 9?
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        "0"+(self.getMonth()+1) :
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        self.getMonth()+1;
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function M() {
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // A short textual representation of a month, three letters
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return monthsShort[self.getMonth()];
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function n() {
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Numeric representation of a month, without leading zeros
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return self.getMonth()+1;
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function O() {
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Difference to Greenwich time (GMT) in hours
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var os = Math.abs(self.getTimezoneOffset());
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var h = ""+Math.floor(os/60);
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var m = ""+(os%60);
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        h.length == 1? h = "0"+h:1;
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m.length == 1? m = "0"+m:1;
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return self.getTimezoneOffset() < 0 ? "+"+h+m : "-"+h+m;
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function r() {
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // RFC 822 formatted date
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var r; // result
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        //  Thu    ,     21          Dec         2000
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        r = D() + ", " + j() + " " + M() + " " + Y() +
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        //        16     :    01     :    07          +0200
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            " " + H() + ":" + i() + ":" + s() + " " + O();
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return r;
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function S() {
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // English ordinal suffix for the day of the month, 2 characters
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return daysSuffix[self.getDate()-1];
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function s() {
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Seconds, with leading zeros
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return new String(self.getSeconds()).length == 1?
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        "0"+self.getSeconds() : self.getSeconds();
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function t() {
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // thanks to Matt Bannon for some much needed code-fixes here!
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var daysinmonths = [null,31,28,31,30,31,30,31,31,30,31,30,31];
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (L()==1 && n()==2) return 29; // leap day
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return daysinmonths[n()];
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function U() {
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return Math.round(self.getTime()/1000);
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function W() {
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Weeknumber, as per ISO specification:
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // http://www.cl.cam.ac.uk/~mgk25/iso-time.html
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // if the day is three days before newyears eve,
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // there's a chance it's "week 1" of next year.
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // here we check for that.
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var beforeNY = 364+L() - z();
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var afterNY  = z();
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var weekday = w()!=0?w()-1:6; // makes sunday (0), into 6.
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (beforeNY <= 2 && weekday <= 2-beforeNY) {
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return 1;
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // similarly, if the day is within threedays of newyears
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // there's a chance it belongs in the old year.
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var ny = new Date("January 1 " + Y() + " 00:00:00");
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var nyDay = ny.getDay()!=0?ny.getDay()-1:6;
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            (afterNY <= 2) &&
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            (nyDay >=4)  &&
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            (afterNY >= (6-nyDay))
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ) {
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Since I'm not sure we can just always return 53,
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // i call the function here again, using the last day
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // of the previous year, as the date, and then just
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // return that week.
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var prevNY = new Date("December 31 " + (Y()-1) + " 00:00:00");
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return prevNY.formatDate("W");
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // week 1, is the week that has the first thursday in it.
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // note that this value is not zero index.
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (nyDay <= 3) {
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // first day of the year fell on a thursday, or earlier.
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return 1 + Math.floor( ( z() + nyDay ) / 7 );
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // first day of the year fell on a friday, or later.
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return 1 + Math.floor( ( z() - ( 7 - nyDay ) ) / 7 );
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function w() {
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Numeric representation of the day of the week
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return self.getDay();
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function Y() {
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // A full numeric representation of a year, 4 digits
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // we first check, if getFullYear is supported. if it
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // is, we just use that. ppks code is nice, but wont
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // work with dates outside 1900-2038, or something like that
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (self.getFullYear) {
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var newDate = new Date("January 1 2001 00:00:00 +0000");
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            var x = newDate .getFullYear();
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (x == 2001) {
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // i trust the method now
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return self.getFullYear();
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // else, do this:
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // codes thanks to ppk:
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // http://www.xs4all.nl/~ppk/js/introdate.html
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var x = self.getYear();
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var y = x % 100;
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        y += (y < 38) ? 2000 : 1900;
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return y;
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function y() {
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // A two-digit representation of a year
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var y = Y()+"";
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return y.substring(y.length-2,y.length);
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    function z() {
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // The day of the year, zero indexed! 0 through 366
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var t = new Date("January 1 " + Y() + " 00:00:00");
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var diff = self.getTime() - t.getTime();
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return Math.floor(diff/1000/60/60/24);
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var self = this;
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (time) {
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // save time
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        var prevTime = self.getTime();
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        self.setTime(time);
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var ia = input.split("");
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var ij = 0;
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (ia[ij]) {
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (ia[ij] == "\\") {
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // this is our way of allowing users to escape stuff
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ia.splice(ij,1);
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (arrayExists(switches,ia[ij])) {
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ia[ij] = eval(ia[ij] + "()");
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ij++;
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // reset time, back to what it was
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (prevTime) {
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        self.setTime(prevTime);
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return ia.join("");
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)var date = new Date("1/1/2007 1:11:11");
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)for (i = 0; i < 500; ++i) {
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var shortFormat = date.formatDate("Y-m-d");
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    var longFormat = date.formatDate("l, F d, Y g:i:s A");
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    date.setTime(date.getTime() + 84266956);
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
300