/**
* timestamp formatting
*/
if(typeof strftime == 'undefined') {
    function strftime(timestamp, format) {
        return (new Date(timestamp*1000)).strftime(format);
    }
}

if(typeof Date.prototype.strftime == 'undefined') {
    Number.prototype.pad =
        function (n,p) {
            var s = '' + this;
            p = p || '0';
            while (s.length < n) s = p + s;
            return s;
        };

    Date.prototype.months = [
            'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli',
            'August', 'September', 'Oktober', 'November', 'Dezember'
        ];
    Date.prototype.weekdays = [
            'Sonntag', 'Montag', 'Dienstag', 'Mittwoch',
            'Donnerstag', 'Freitag', 'Samstag'
        ];
    
    Date.prototype.getWeek = function() {
        var onejan = new Date(this.getFullYear(),0,1);
        return Math.ceil((((this - onejan) / 86400000) + onejan.getDay()+1)/7);
    }

    Date.prototype.getUTCTime = function() {
        return Date.UTC(this.getFullYear(), this.getMonth(), this.getDate(), this.getHours(), this.getMinutes(),
            this.getSeconds(), this.getMilliseconds());
      };

      Date.prototype.getTimeSince = function(d) {
        return this.getUTCTime() - d.getUTCTime();
      };
    
    Date.prototype.getWeek = function () {
        var dowOffset = 1;
        /*getWeek() was developed by Nick Baicoianu at MeanFreePath: http://www.meanfreepath.com */
        var newYear = new Date(this.getFullYear(),0,1);
        var day = newYear.getDay() - dowOffset; //the day of week the year begins on
        day = (day >= 0 ? day : day + 7);
        var daynum = Math.floor((this.getTime() - newYear.getTime() -
        (this.getTimezoneOffset()-newYear.getTimezoneOffset())*60000)/86400000) + 1;
        var weeknum;
        //if the year starts before the middle of a week
        if(day < 4) {
        weeknum = Math.floor((daynum+day-1)/7) + 1;
        if(weeknum > 52) {
        nYear = new Date(this.getFullYear() + 1,0,1);
        nday = nYear.getDay() - dowOffset;
        nday = nday >= 0 ? nday : nday + 7;
        /*if the next year starts before the middle of
        the week, it is week #1 of that year*/
        weeknum = nday < 4 ? 1 : 53;
        }
        }
        else {
        weeknum = Math.floor((daynum+day-1)/7);
        }
        return weeknum;
    };

    Date.prototype.dpm = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];

    Date.prototype.strftime_f = {
            A: function (d) { return d.weekdays[d.getDay()] },
            a: function (d) { return d.weekdays[d.getDay()].substring(0,3) },
            B: function (d) { return d.months[d.getMonth()] },
            b: function (d) { return d.months[d.getMonth()].substring(0,3) },
            C: function (d) { return Math.floor(d.getFullYear()/100); },
            c: function (d) { return d.toString() },
            D: function (d) {
                    return d.strftime_f.m(d) + '/' +
                        d.strftime_f.d(d) + '/' + d.strftime_f.y(d);
                },
            d: function (d) { return d.getDate().pad(2,'0') },
            e: function (d) { return d.getDate().pad(2,' ') },
            F: function (d) {
                    return d.strftime_f.Y(d) + '-' + d.strftime_f.m(d) + '-' +
                        d.strftime_f.d(d);
                },
            H: function (d) { return d.getHours().pad(2,'0') },
            I: function (d) { return ((d.getHours() % 12 || 12).pad(2)) },
            j: function (d) {
                    var t = d.getDate();
                    var m = d.getMonth() - 1;
                    if (m > 1) {
                        var y = d.getYear();
                        if (((y % 100) == 0) && ((y % 400) == 0)) ++t;
                        else if ((y % 4) == 0) ++t;
                    }
                    while (m > -1) t += d.dpm[m--];
                    return t.pad(3,'0');
                },
            k: function (d) { return d.getHours().pad(2,' ') },
            l: function (d) { return ((d.getHours() % 12 || 12).pad(2,' ')) },
            M: function (d) { return d.getMinutes().pad(2,'0') },
            m: function (d) { return (d.getMonth()+1).pad(2,'0') },
            n: function (d) { return "\n" },
            p: function (d) { return (d.getHours() > 11) ? 'PM' : 'AM' },
            R: function (d) { return d.strftime_f.H(d) + ':' + d.strftime_f.M(d) },
            r: function (d) {
                    return d.strftime_f.I(d) + ':' + d.strftime_f.M(d) + ':' +
                        d.strftime_f.S(d) + ' ' + d.strftime_f.p(d);
                },
            S: function (d) { return d.getSeconds().pad(2,'0') },
    /*        S: function (d) { return false }, */
            T: function (d) {
                    return d.strftime_f.H(d) + ':' + d.strftime_f.M(d) + ':' +
                        d.strftime_f.S(d);
                },
            t: function (d) { return "\t" },
            /*U: function (d) { return d.getWeek() }, */
            u: function (d) { return(d.getDay() || 7) },
            V: function (d) { return d.getWeek() },
            v: function (d) {
                    return d.strftime_f.e(d) + '-' + d.strftime_f.b(d) + '-' +
                        d.strftime_f.Y(d);
                },
    /*        W: function (d) { return false }, */
            w: function (d) { return d.getDay() },
            X: function (d) { return d.toTimeString() }, // wrong?
            x: function (d) { return d.toDateString() }, // wrong?
            Y: function (d) { return d.getFullYear() },
            y: function (d) { return (d.getYear() % 100).pad(2) },
    //        Z: function (d) { return d.toString().match(/\((.+)\)$/)[1]; },
    //        z: function (d) { return d.getTimezoneOffset() }, // wrong
    //        z: function (d) { return d.toString().match(/\sGMT([+-]\d+)/)[1]; },
            '%': function (d) { return '%' }
        };

    Date.prototype.strftime_f['+'] = Date.prototype.strftime_f.c;
    Date.prototype.strftime_f.h = Date.prototype.strftime_f.b;

    Date.prototype.strftime = function (fmt) {
        var r = '';
        var n = 0;
        while(n < fmt.length) {
            var c = fmt.substring(n, n+1);
            if (c == '%') {
                c = fmt.substring(++n, n+1);
                r += (this.strftime_f[c]) ? this.strftime_f[c](this) : c;
            } else r += c;
            ++n;
        }
        return r;
    };

	
	Date.prototype.setISO8601 = function(dString){

	var regexp = /(\d\d\d\d)(-)?(\d\d)(-)?(\d\d)(T)?(\d\d)(:)?(\d\d)(:)?(\d\d)(\.\d+)?(Z|([+-])(\d\d)(:)?(\d\d))/;

	if (dString.toString().match(new RegExp(regexp))) {
	var d = dString.match(new RegExp(regexp));
	var offset = 0;

	this.setUTCDate(1);
	this.setUTCFullYear(parseInt(d[1],10));
	this.setUTCMonth(parseInt(d[3],10) - 1);
	this.setUTCDate(parseInt(d[5],10));
	this.setUTCHours(parseInt(d[7],10));
	this.setUTCMinutes(parseInt(d[9],10));
	this.setUTCSeconds(parseInt(d[11],10));
	if (d[12])
	this.setUTCMilliseconds(parseFloat(d[12]) * 1000);
	else
	this.setUTCMilliseconds(0);
	if (d[13] != 'Z') {
	offset = (d[15] * 60) + parseInt(d[17],10);
	offset *= ((d[14] == '-') ? -1 : 1);
	this.setTime(this.getTime() - offset * 60 * 1000);
	}
	}
	else {
	this.setTime(Date.parse(dString));
	}
	return this;
	};

}
