/*
	w3cdtf.js -- Copyright (C) 2007, Kaigo

	reference: http://www.hesperus.net/javascript/w3cdtf.shtml
*/

Date.prototype.toW3CDTF = function(granularity, tzd) {
	function valueToString(value, length) {
		value = value.toString(10);

		while (value.length < length) {
			value = "0" + value;
		}

		return value;
	}

	var offset = this.getTimezoneOffset();
	var returnValue = "";

	switch (granularity) {
		case 1:
		case 2:
		case 3:
			break;

		default:
			switch (tzd) {
				case "GMT":
				case "UTC":
				case "Z":
					this.setMinutes(this.getMinutes() + offset);
					offset = 0;
					break;

				default:
					if (tzd && tzd.match(/([\+\-]\d{2}):(\d{2})/)) {
						this.setMinutes(this.getMinutes() + offset);
						offset = parseInt(RegExp.$1, 10);
						offset = -60 * offset - ((offset < 0) ? -1 : 1) * parseInt(RegExp.$2, 10);
						this.setMinutes(this.getMinutes() - offset);
					}
			}

			if (offset) {
				returnValue += (offset < 0) ? "+" : "-";
				offset = ((offset < 0) ? -1 : 1) * offset;
				returnValue += valueToString(offset / 60, 2) + ":" + valueToString(offset % 60, 2);
			} else {
				returnValue += "Z";
			}
	}

	switch (granularity) {
		case 6:
			returnValue = ".000" + returnValue;

		default:
		case 5:
			returnValue = ":" + valueToString(this.getSeconds(), 2) + returnValue;

		case 4:
			returnValue = ":" + valueToString(this.getMinutes(), 2) + returnValue;
			returnValue = "T" + valueToString(this.getHours(), 2) + returnValue;

		case 3:
			returnValue = "-" + valueToString(this.getDate(), 2) + returnValue;

		case 2:
			returnValue = "-" + valueToString(this.getMonth() + 1, 2) + returnValue;

		case 1:
			// 2007/10/20 [S] Kaigo
			//returnValue = valueToString(this.getYear(), 4) + returnValue;
			var year = this.getYear();
			year += (year < 1900) ? 1900 : 0;
			returnValue = valueToString(year, 4) + returnValue;
			// 2007/10/20 [E] Kaigo
	}

	return returnValue;
}

Date.fromW3CDTF = function(text) {
	var returnValue = new Date("1900/01/01");
	var granularity = 0;
	var tzd = 0;
	var offset = 0;
	var matched = null;

	if (matched = text.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\.(\d+)([\+\-]\d{2}):(\d{2})/)) {
		granularity = 6;
		tzd = 1;
	} else if (matched = text.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\.(\d+)Z/)) {
		granularity = 6;
		tzd = 2;
	} else if (matched = text.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})([\+\-]\d{2}):(\d{2})/)) {
		granularity = 5;
		tzd = 1;
	} else if (matched = text.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z/)) {
		granularity = 5;
		tzd = 2;
	} else if (matched = text.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})([\+\-]\d{2}):(\d{2})/)) {
		granularity = 4;
		tzd = 1;
	} else if (matched = text.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})Z/)) {
		granularity = 4;
		tzd = 2;
	} else if (matched = text.match(/(\d{4})-(\d{2})-(\d{2})/)) {
		granularity = 3;
	} else if (matched = text.match(/(\d{4})-(\d{2})/)) {
		granularity = 2;
	} else if (matched = text.match(/(\d{4})/)) {
		granularity = 1;
	}

	switch (granularity) {
		case 6:
		case 5:
			returnValue.setSeconds(parseInt(matched[6], 10));

		case 4:
			returnValue.setMinutes(parseInt(matched[5], 10));
			returnValue.setHours(parseInt(matched[4], 10));

		case 3:
			returnValue.setDate(parseInt(matched[3], 10));

		case 2:
			returnValue.setMonth(parseInt(matched[2], 10) - 1);

		case 1:
			returnValue.setYear(parseInt(matched[1], 10));
	}

	switch (tzd) {
		case 1:
			offset = parseInt(matched[matched.length - 2], 10);
			offset = 60 * offset + ((offset < 0) ? -1 : 1) * parseInt(matched[matched.length - 1], 10);

		case 2:
			returnValue.setMinutes(returnValue.getMinutes() - offset - returnValue.getTimezoneOffset());
	}

	return returnValue;
}
