/* * copyright (c) 2004 baron schwartz * * this program is free software; you can redistribute it and/or modify it * under the terms of the gnu lesser general public license as published by the * free software foundation, version 2.1. * * this program is distributed in the hope that it will be useful, but without * any warranty; without even the implied warranty of merchantability or fitness * for a particular purpose. see the gnu lesser general public license for more * details. */ date.parsefunctions = {count:0}; date.parseregexes = []; date.formatfunctions = {count:0}; date.prototype.dateformat = function(format) { if (date.formatfunctions[format] == null) { date.createnewformat(format); } var func = date.formatfunctions[format]; return this[func](); } date.createnewformat = function(format) { var funcname = "format" + date.formatfunctions.count++; date.formatfunctions[format] = funcname; var code = "date.prototype." + funcname + " = function(){return "; var special = false; var ch = ''; for (var i = 0; i < format.length; ++i) { ch = format.charat(i); if (!special && ch == "\\") { special = true; } else if (special) { special = false; code += "'" + string.escape(ch) + "' + "; } else { code += date.getformatcode(ch); } } eval(code.substring(0, code.length - 3) + ";}"); } date.getformatcode = function(character) { switch (character) { case "d": return "string.leftpad(this.getdate(), 2, '0') + "; case "d": return "date.daynames[this.getday()].substring(0, 3) + "; case "e": return "date.daynamesmid[this.getday()].substring(1,2) + "; case "e": return "date.daynamesmid[this.getday()] + "; case "j": return "this.getdate() + "; case "l": return "date.daynames[this.getday()] + "; case "s": return "this.getsuffix() + "; case "w": return "this.getday() + "; case "z": return "this.getdayofyear() + "; case "w": return "this.getweekofyear() + "; case "f": return "date.monthnames[this.getmonth()] + "; case "m": return "string.leftpad(this.getmonth() + 1, 2, '0') + "; case "m": return "date.monthnames[this.getmonth()].substring(0, 3) + "; case "n": return "(this.getmonth() + 1) + "; case "t": return "this.getdaysinmonth() + "; case "l": return "(this.isleapyear() ? 1 : 0) + "; case "y": return "this.getfullyear() + "; case "y": return "('' + this.getfullyear()).substring(2, 4) + "; case "a": return "(this.gethours() < 12 ? 'am' : 'pm') + "; case "a": return "(this.gethours() < 12 ? 'am' : 'pm') + "; case "g": return "((this.gethours() %12) ? this.gethours() % 12 : 12) + "; case "g": return "this.gethours() + "; case "h": return "string.leftpad((this.gethours() %12) ? this.gethours() % 12 : 12, 2, '0') + "; case "h": return "string.leftpad(this.gethours(), 2, '0') + "; case "i": return "string.leftpad(this.getminutes(), 2, '0') + "; case "s": return "string.leftpad(this.getseconds(), 2, '0') + "; case "o": return "this.getgmtoffset() + "; case "t": return "this.gettimezone() + "; case "z": return "(this.gettimezoneoffset() * -60) + "; default: return "'" + string.escape(character) + "' + "; } } date.parsedate = function(input, format) { if (date.parsefunctions[format] == null) { date.createparser(format); } var func = date.parsefunctions[format]; return date[func](input); } date.createparser = function(format) { var funcname = "parse" + date.parsefunctions.count++; var regexnum = date.parseregexes.length; var currentgroup = 1; date.parsefunctions[format] = funcname; var code = "date." + funcname + " = function(input){\n" + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1;\n" + "var d = new date();\n" + "y = d.getfullyear();\n" + "m = d.getmonth();\n" + "d = d.getdate();\n" + "var results = input.match(date.parseregexes[" + regexnum + "]);\n" + "if (results && results.length > 0) {" var regex = ""; var special = false; var ch = ''; for (var i = 0; i < format.length; ++i) { ch = format.charat(i); if (!special && ch == "\\") { special = true; } else if (special) { special = false; regex += string.escape(ch); } else { obj = date.formatcodetoregex(ch, currentgroup); currentgroup += obj.g; regex += obj.s; if (obj.g && obj.c) { code += obj.c; } } } code += "if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n" + "{return new date(y, m, d, h, i, s);}\n" + "else if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n" + "{return new date(y, m, d, h, i);}\n" + "else if (y > 0 && m >= 0 && d > 0 && h >= 0)\n" + "{return new date(y, m, d, h);}\n" + "else if (y > 0 && m >= 0 && d > 0)\n" + "{return new date(y, m, d);}\n" + "else if (y > 0 && m >= 0)\n" + "{return new date(y, m);}\n" + "else if (y > 0)\n" + "{return new date(y);}\n" + "}return null;}"; date.parseregexes[regexnum] = new regexp("^" + regex + "$"); eval(code); } date.formatcodetoregex = function(character, currentgroup) { switch (character) { case "d": return {g:0, c:null, s:"(?:周日|周一|周二|周三|周四|周五|周六)"}; case "j": case "d": return {g:1, c:"d = parseint(results[" + currentgroup + "], 10);\n", s:"(\\d{1,2})"}; case "l": return {g:0, c:null, s:"(?:" + date.daynames.join("|") + ")"}; case "s": return {g:0, c:null, s:"(?:st|nd|rd|th)"}; case "w": return {g:0, c:null, s:"\\d"}; case "z": return {g:0, c:null, s:"(?:\\d{1,3})"}; case "w": return {g:0, c:null, s:"(?:\\d{2})"}; case "f": return {g:1, c:"m = parseint(date.monthnumbers[results[" + currentgroup + "].substring(0, 3)], 10);\n", s:"(" + date.monthnames.join("|") + ")"}; case "m": return {g:1, c:"m = parseint(date.monthnumbers[results[" + currentgroup + "]], 10);\n", s:"(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)"}; case "n": case "m": return {g:1, c:"m = parseint(results[" + currentgroup + "], 10) - 1;\n", s:"(\\d{1,2})"}; case "t": return {g:0, c:null, s:"\\d{1,2}"}; case "l": return {g:0, c:null, s:"(?:1|0)"}; case "y": return {g:1, c:"y = parseint(results[" + currentgroup + "], 10);\n", s:"(\\d{4})"}; case "y": return {g:1, c:"var ty = parseint(results[" + currentgroup + "], 10);\n" + "y = ty > date.y2kyear ? 1900 + ty : 2000 + ty;\n", s:"(\\d{1,2})"}; case "a": return {g:1, c:"if (results[" + currentgroup + "] == 'am') {\n" + "if (h == 12) { h = 0; }\n" + "} else { if (h < 12) { h += 12; }}", s:"(am|pm)"}; case "a": return {g:1, c:"if (results[" + currentgroup + "] == 'am') {\n" + "if (h == 12) { h = 0; }\n" + "} else { if (h < 12) { h += 12; }}", s:"(am|pm)"}; case "g": case "g": case "h": case "h": return {g:1, c:"h = parseint(results[" + currentgroup + "], 10);\n", s:"(\\d{1,2})"}; case "i": return {g:1, c:"i = parseint(results[" + currentgroup + "], 10);\n", s:"(\\d{2})"}; case "s": return {g:1, c:"s = parseint(results[" + currentgroup + "], 10);\n", s:"(\\d{2})"}; case "o": return {g:0, c:null, s:"[+-]\\d{4}"}; case "t": return {g:0, c:null, s:"[a-z]{3}"}; case "z": return {g:0, c:null, s:"[+-]\\d{1,5}"}; default: return {g:0, c:null, s:string.escape(character)}; } } date.prototype.gettimezone = function() { return this.tostring().replace( /^.*? ([a-z]{3}) [0-9]{4}.*$/, "$1").replace( /^.*?\(([a-z])[a-z]+ ([a-z])[a-z]+ ([a-z])[a-z]+\)$/, "$1$2$3"); } date.prototype.getgmtoffset = function() { return (this.gettimezoneoffset() > 0 ? "-" : "+") + string.leftpad(math.floor(this.gettimezoneoffset() / 60), 2, "0") + string.leftpad(this.gettimezoneoffset() % 60, 2, "0"); } date.prototype.getdayofyear = function() { var num = 0; date.daysinmonth[1] = this.isleapyear() ? 29 : 28; for (var i = 0; i < this.getmonth(); ++i) { num += date.daysinmonth[i]; } return num + this.getdate() - 1; } date.prototype.getweekofyear = function() { // skip to thursday of this week var now = this.getdayofyear() + (4 - this.getday()); // find the first thursday of the year var jan1 = new date(this.getfullyear(), 0, 1); var then = (7 - jan1.getday() + 4); document.write(then); return string.leftpad(((now - then) / 7) + 1, 2, "0"); } date.prototype.isleapyear = function() { var year = this.getfullyear(); return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year))); } date.prototype.getfirstdayofmonth = function() { var day = (this.getday() - (this.getdate() - 1)) % 7; return (day < 0) ? (day + 7) : day; } date.prototype.getlastdayofmonth = function() { var day = (this.getday() + (date.daysinmonth[this.getmonth()] - this.getdate())) % 7; return (day < 0) ? (day + 7) : day; } date.prototype.getdaysinmonth = function() { date.daysinmonth[1] = this.isleapyear() ? 29 : 28; return date.daysinmonth[this.getmonth()]; } date.prototype.getfirstdateofcnweek = function() { var day = this.getday() > 0 ? this.getday() : 7; return new date(this - (day - 1) * 86400000); }; date.prototype.getlastdateofcnweek = function() { var day = this.getday() > 0 ? this.getday() : 7; return new date(this + (7 - day) * 86400000); }; date.prototype.getcnweekdates = function() { var firthday = this.getfirstdateofcnweek().gettime(); var week = []; for ( var i = 0; i < 7; i++) { week.push(new date(firthday + 86400000*i)); } return week; }; date.prototype.getfirstdateofmonth = function() { var date = new date(this); date.setdate(1); return date; }; date.prototype.getlastdateofmonth = function() { var nextmonthdate = new date(this); nextmonthdate.setmonth(this.getmonth() + 1); nextmonthdate.setdate(1); return new date(nextmonthdate - 86400000); }; date.prototype.getsuffix = function() { switch (this.getdate()) { case 1: case 21: case 31: return "st"; case 2: case 22: return "nd"; case 3: case 23: return "rd"; default: return "th"; } } string.escape = function(string) { return string.replace(/('|\\)/g, "\\$1"); } string.leftpad = function (val, size, ch) { var result = new string(val); if (ch == null) { ch = " "; } while (result.length < size) { result = ch + result; } return result; } date.daysinmonth = [31,28,31,30,31,30,31,31,30,31,30,31]; date.monthnames = ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"]; date.daynames = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]; date.daynamesmid = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"]; date.y2kyear = 50; date.monthnumbers = { jan:0, feb:1, mar:2, apr:3, may:4, jun:5, jul:6, aug:7, sep:8, oct:9, nov:10, dec:11}; date.patterns = { iso8601longpattern:"y-m-d h:i:s", iso8601shortpattern:"y-m-d", shortdatepattern: "n/j/y", longdatepattern: "l, f d, y", fulldatetimepattern: "l, f d, y g:i:s a", monthdaypattern: "f d", shorttimepattern: "g:i a", longtimepattern: "g:i:s a", sortabledatetimepattern: "y-m-d\\th:i:s", universalsortabledatetimepattern: "y-m-d h:i:so", yearmonthpattern: "f, y"}; /** * 对date的扩展,将 date 转化为指定格式的string * 月(m)、日(d)、12小时(h)、24小时(h)、分(m)、秒(s)、周(e)、季度(q) 可以用 1-2 个占位符 * 年(y)可以用 1-4 个占位符,毫秒(s)只能用 1 个占位符(是 1-3 位的数字) * eg: * (new date()).pattern("yyyy-mm-dd hh:mm:ss.s") ==> 2006-07-02 08:09:04.423 * (new date()).pattern("yyyy-mm-dd e hh:mm:ss") ==> 2009-03-10 二 20:09:04 * (new date()).pattern("yyyy-mm-dd ee hh:mm:ss") ==> 2009-03-10 周二 08:09:04 * (new date()).pattern("yyyy-mm-dd eee hh:mm:ss") ==> 2009-03-10 星期二 08:09:04 * (new date()).pattern("yyyy-m-d h:m:s.s") ==> 2006-7-2 8:9:4.18 */ date.prototype.pattern=function(fmt) { var o = { "m+" : this.getmonth()+1, //月份 "d+" : this.getdate(), //日 "h+" : this.gethours()%12 == 0 ? 12 : this.gethours()%12, //小时 "h+" : this.gethours(), //小时 "m+" : this.getminutes(), //分 "s+" : this.getseconds(), //秒 "q+" : math.floor((this.getmonth()+3)/3), //季度 "s" : this.getmilliseconds() //毫秒 }; var week = { "0" : "\u65e5", "1" : "\u4e00", "2" : "\u4e8c", "3" : "\u4e09", "4" : "\u56db", "5" : "\u4e94", "6" : "\u516d" }; if(/(y+)/.test(fmt)){ fmt=fmt.replace(regexp.$1, (this.getfullyear()+"").substr(4 - regexp.$1.length)); } if(/(e+)/.test(fmt)){ fmt=fmt.replace(regexp.$1, ((regexp.$1.length>1) ? (regexp.$1.length>2 ? "\u661f\u671f" : "\u5468") : "")+week[this.getday()+""]); } for(var k in o){ if(new regexp("("+ k +")").test(fmt)){ fmt = fmt.replace(regexp.$1, (regexp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length))); } } return fmt; }