/**
 * 預設的樣式為「yyyy-MM-dd HH:mm:ss SSS」；樣式的字元為「yMdHmsS」，可參考 Java 的 DateFormat。
 * @param pattern 呈現的樣式，預設為「yyyy-MM-dd HH:mm:ss SSS」。
 * @param formatSymbols 樣式的字元，預設為「yMdHmsS」。
 */
function DateFormat(pattern, formatSymbols) {
	if (typeof pattern == 'undefined')
		pattern = 'yyyy-MM-dd HH:mm:ss SSS';
	
	if (typeof formatSymbols == 'undefined')
		formatSymbols = 'yMdHmsS';
	
	this.pattern = pattern;
	this.formatSymbols = formatSymbols;
}

/**
 * 根據 pattern 將 date 物件格式化。
 * @param date Date 物件。
 * @return 回傳依 pattern 樣式格式化後的日期字串。 
 */
DateFormat.prototype.format = function(date) {
	var time = getTime(date);
	
	var cs = this.formatSymbols.split('');
	var fs = this.pattern.split('');
	var ds = time.split('');
	
	// 年月日時分秒及毫秒的結束位置
	var y = 3;
	var M = 6;
	var d = 9;
	var H = 12;
	var m = 15;
	var s = 18;
	var S = 22;
	
	// 逐位替換年月日時分秒和毫秒
	for (var idx = fs.length - 1; idx > -1; idx--) {
		switch (fs[idx]) {
			case cs[0]: fs[idx] = ds[y--]; break;
			case cs[1]: fs[idx] = ds[M--]; break;
			case cs[2]: fs[idx] = ds[d--]; break;
			case cs[3]: fs[idx] = ds[H--]; break;
			case cs[4]: fs[idx] = ds[m--]; break;
			case cs[5]: fs[idx] = ds[s--]; break;
			case cs[6]: fs[idx] = ds[S--]; break;
		}
	}
	
	return fs.join('');
}

/**
 * 根據 pattern 解析 date 字串所指定的日期字串，並轉化為 Date 物件。
 * @param date 以 pattern 樣式所指定的日期字串。
 * @return 回傳依 pattern 樣式解析化的 Date 物件。 
 */
DateFormat.prototype.parse = function(date) {
	var y = '';
	var M = '';
	var d = '';
	var H = '';
	var m = '';
	var s = '';
	var S = '';
	
	var cs = this.formatSymbols.split('');
	var ds = this.pattern.split('');
	var size = Math.min(ds.length, date.length);
	
	for (var idx = 0; idx < size; idx++) {
		switch (ds[idx]) {
			case cs[0]: y += date.charAt(idx); break;
			case cs[1]: M += date.charAt(idx); break;
			case cs[2]: d += date.charAt(idx); break;
			case cs[3]: H += date.charAt(idx); break;
			case cs[4]: m += date.charAt(idx); break;
			case cs[5]: s += date.charAt(idx); break;
			case cs[6]: S += date.charAt(idx); break;
		}
	}
	
	y = y.length < 1 ? 0 : parseInt(y, 10);
	M = M.length < 1 ? 0 : parseInt(M, 10);
	d = d.length < 1 ? 0 : parseInt(d, 10);
	H = H.length < 1 ? 0 : parseInt(H, 10);
	m = m.length < 1 ? 0 : parseInt(m, 10);
	s = s.length < 1 ? 0 : parseInt(s, 10);
	S = S.length < 1 ? 0 : parseInt(S, 10);
	
	return new Date(y, M - 1, d, H, m, s, S);
}

function getTime(date) {
	if (typeof date == 'string') {
		if (date.length == 8)
			return date.substring(0, 4) + '-' + date.substring(4, 6) + '-' + date.substring(6, 8);
		else if (date.length == 12)
			return date.substring(0, 4) + '-' + date.substring(4, 6) + '-' + date.substring(6, 8) + ' ' + date.substring(8, 10) + ':' + date.substring(10, 12);
		else if (date.length == 14)
			return date.substring(0, 4) + '-' + date.substring(4, 6) + '-' + date.substring(6, 8) + ' ' + date.substring(8, 10) + ':' + date.substring(10, 12) + ':' + date.substring(12, 14);
		else
			return '日期格式錯誤！';
	} else if (typeof date == 'undefined')
		date = new Date();
	
	var y = date.getFullYear();
	var M = date.getMonth() + 1;
	var d = date.getDate();
	var h = date.getHours();
	var m = date.getMinutes();
	var s = date.getSeconds();
	var S = date.getTime() % 1000;
	
	var sFormat = y + '-';
	sFormat += (M < 10 ? '0' : '') + M + '-';
	sFormat += (d < 10 ? '0' : '') + d + ' ';
	sFormat += (h < 10 ? '0' : '') + h + ':';
	sFormat += (m < 10 ? '0' : '') + m + ':';
	sFormat += (s < 10 ? '0' : '') + s + ' ';
	sFormat += ('00' + S).substr(-3, 3);
	
	return sFormat;
}
