/**
* Date Text String Format / Convert
* 1:10 2009-9-1 www.lxasp.com
*
* RIP and MOD from :
* www.dynarch.com/projects/calendar
* http://www.blogjava.net/rox/archive/2009/01/23/249031.html
*
* add support year from 0 to 9999 when use "yyyy" or "%Y"
*
*/
(function() {
datetext = {};
datetext.isDate =function(v){
return(typeof v!="object") ? false : (v.constructor==Date) ? !isNaN(v) : false;
}
datetext.toDate = function(str, fmt, isjoin) {
var getDate = function(dateString, formatString){
var y4 = "([0-9]{4})",
y2 = "([0-9]{2})",
yi = -1,
M2 = "(0[1-9]|1[0-2])",
M1 = "([1-9]|1[0-2])",
Mi = -1,
d2 = "(0[1-9]|[1-2][0-9]|30|31)",
d1 = "([1-9]|[1-2][0-9]|30|31)",
di = -1,
H2 = "([0-1][0-9]|20|21|22|23)",
H1 = "([0-9]|1[0-9]|20|21|22|23)",
Hi = -1,
m2 = "([0-5][0-9])",
m1 = "([0-9]|[1-5][0-9])",
mi = -1,
s2 = "([0-5][0-9])",
s1 = "([0-9]|[1-5][0-9])",
si = -1,
regexp;
var validateDate = function(dateString, formatString){
if(dateString=="") return;
var reg = formatString;
reg = reg.replace(/yyyy/, y4);
reg = reg.replace(/yy/, y2);
reg = reg.replace(/mm/, M2);
reg = reg.replace(/m/, M1);
reg = reg.replace(/dd/, d2);
reg = reg.replace(/d/, d1);
reg = reg.replace(/HH/, H2);
reg = reg.replace(/H/, H1);
reg = reg.replace(/MM/, m2);
reg = reg.replace(/M/, m1);
reg = reg.replace(/SS/, s2);
reg = reg.replace(/S/, s1);
reg = new RegExp("^"+reg+"$");
regexp = reg;
return reg.test(dateString);
},
validateIndex =function(formatString){
var ia = new Array();
var i = 0;
yi = formatString.search(/yyyy/);
if ( yi < 0 ) yi = formatString.search(/yy/);
if (yi >= 0) {
ia[i] = yi;
i++;
}
Mi = formatString.search(/mm/);
if ( Mi < 0 ) Mi = formatString.search(/m/);
if (Mi >= 0) {
ia[i] = Mi;
i++;
}
di = formatString.search(/dd/);
if ( di < 0 ) di = formatString.search(/d/);
if (di >= 0) {
ia[i] = di;
i++;
}
Hi = formatString.search(/HH/);
if ( Hi < 0 ) Hi = formatString.search(/H/);
if (Hi >= 0) {
ia[i] = Hi;
i++;
}
mi = formatString.search(/MM/);
if ( mi < 0 ) mi = formatString.search(/M/);
if (mi >= 0) {
ia[i] = mi;
i++;
}
si = formatString.search(/SS/);
if ( si < 0 ) si = formatString.search(/S/);
if (si >= 0) {
ia[i] = si;
i++;
}
var ia2 = new Array(yi, Mi, di, Hi, mi, si);
for(i=0; i<ia.length-1; i++)
for(j=0;j<ia.length-1-i;j++)
if(ia[j]>ia[j+1]) {
temp=ia[j];
ia[j]=ia[j+1];
ia[j+1]=temp;
}
for (i=0; i<ia.length ; i++)
for (j=0; j<ia2.length; j++)
if(ia[i]==ia2[j]) {
ia2[j] = i;
}
return ia2;
};
if(validateDate(dateString, formatString)) {
var now = new Date(),
vals = regexp.exec(dateString),
index = validateIndex(formatString),
year = index[0]>=0?vals[index[0] + 1]:now.getFullYear(),
month = index[1]>=0?(vals[index[1] + 1]-1):now.getMonth(),
day = index[2]>=0?vals[index[2] + 1]:now.getDate(),
hour = index[3]>=0?vals[index[3] + 1]:"",
minute = index[4]>=0?vals[index[4] + 1]:"",
second = index[5]>=0?vals[index[5] + 1]:"",
validate;
if (hour == "")
validate = new Date(year, month, day);
else
validate = new Date(year, month, day, hour, minute, second);
if(!datetext.isDate(validate)) return new Date();
if(formatString.search(/yyyy/)<0){
var y = year;
y=parseInt( ('' + y).length==4 ? ('' + y).substr(2, 2) : (''+y).length==2 ? y : '0'+y ,10) ;
(y < 100) && (y += (y > 29) ? 1900 : 2000);
validate.setFullYear(y);
}else{validate.setFullYear(year);}
if(validate.getDate()==day) return validate;
}
return new Date();
};
if(isjoin)return getDate(str,fmt);
var today = new Date(), ret,
y = 0,
m = -1,
d = 0,
a = str.split(/\W+/),
b = fmt.match(/%./g),
i = 0, j = 0,
hr = 0,
min = 0,sec=0;
for (i = 0; i < a.length; ++i) {
if (!a[i])
continue;
switch (b[i]) {
case "%d":
case "%e":
d = parseInt(a[i], 10);
break;
case "%m":
m = parseInt(a[i], 10) - 1;
break;
case "%Y":
y = parseInt(a[i], 10);
break;
case "%y":
y = parseInt(a[i], 10);
(y < 100) && (y += (y > 29) ? 1900 : 2000);
break;
case "%b":
case "%B":
for (j = 0; j < 12; ++j) {
if (datetext._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; }
}
break;
case "%H":
case "%I":
case "%k":
case "%l":
hr = parseInt(a[i], 10);
break;
case "%P":
case "%p":
if (/pm/i.test(a[i]) && hr < 12)
hr += 12;
else if (/am/i.test(a[i]) && hr >= 12)
hr -= 12;
break;
case "%M":
min = parseInt(a[i], 10);
break;
case "%S":
sec = parseInt(a[i], 10);
break;
}
}
if (isNaN(y)) y = today.getFullYear();
if (isNaN(m)) m = today.getMonth();
if (isNaN(d)) d = today.getDate();
if (isNaN(hr)) hr = today.getHours();
if (isNaN(min)) min = today.getMinutes();
if (isNaN(sec)) sec = today.getSeconds();
if (y != 0 && m != -1 && d != 0){
ret=new Date(y, m, d, hr, min, sec);
if(datetext.isDate(ret)){
ret.setFullYear(y);return ret;
}else{return today}
}
y = 0; m = -1; d = 0;
for (i = 0; i < a.length; ++i) {
if (a[i].search(/[a-zA-Z]+/) != -1) {
var t = -1;
for (j = 0; j < 12; ++j) {
if (datetext._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; }
}
if (t != -1) {
if (m != -1) {
d = m+1;
}
m = t;
}
} else if (parseInt(a[i], 10) <= 12 && m == -1) {
m = a[i]-1;
} else if (parseInt(a[i], 10) > 31 && y == 0) {
y = parseInt(a[i], 10);
(y < 100) && (y += (y > 29) ? 1900 : 2000);
} else if (d == 0) {
d = a[i];
}
}
if (y == 0)
y = today.getFullYear();
if (m != -1 && d != 0){
ret=new Date(y, m, d, hr, min, sec);
if(datetext.isDate(ret)){
ret.setFullYear(y);return ret;
}else{return today}
}
return today;
};
/** Returns the number of day in the year. */
datetext.getDayOfYear = function(self) {
var SECOND = 1000,
MINUTE = 60 * SECOND,
HOUR = 60 * MINUTE,
DAY = 24 * HOUR,
WEEK = 7 * DAY;
var now = new Date(self.getFullYear(), self.getMonth(), self.getDate(), 0, 0, 0);
now.setFullYear(self.getFullYear());
var then = new Date(self.getFullYear(), 0, 0, 0, 0, 0);
then.setFullYear(self.getFullYear());
var time = now - then;
return Math.floor(time / DAY);
};
/** Returns the number of the week in year, as defined in ISO 8601. */
datetext.getWeekNumber = function(self) {
var d = new Date(self.getFullYear(), self.getMonth(), self.getDate(), 0, 0, 0);
d.setFullYear(self.getFullYear());
var DoW = d.getDay();
d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu
var ms = d.valueOf(); // GMT
d.setMonth(0);
d.setDate(4); // Thu in Week 1
return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1;
};
/** Prints the date in a string according to the given format. */
datetext.toText = function (self,str) {
/// detect a special case of "web browser"
var is_ie = ( /msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent) ),
is_ie5 = ( is_ie && /msie 5\.0/i.test(navigator.userAgent) ),
is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent),
m = self.getMonth(),
d = self.getDate(),
y = self.getFullYear(),
wn = datetext.getWeekNumber(self),
w = self.getDay(),
s = {},
hr = self.getHours(),
pm = (hr >= 12),
ir = (pm) ? (hr - 12) : hr,
dy = datetext.getDayOfYear(self);
if (ir == 0)
ir = 12;
var min = self.getMinutes(),
sec = self.getSeconds();
s["%a"] = datetext._SDN[w]; // abbreviated weekday name [FIXME: I18N]
s["%A"] = datetext._DN[w]; // full weekday name
s["%b"] = datetext._SMN[m]; // abbreviated month name [FIXME: I18N]
s["%B"] = datetext._MN[m]; // full month name
// FIXME: %c : preferred date and time representation for the current locale
s["%C"] = 1 + Math.floor(y / 100); // the century number
s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31)
s["%e"] = d; // the day of the month (range 1 to 31)
// FIXME: %D : american date style: %m/%d/%y
// FIXME: %E, %F, %G, %g, %h (man strftime)
s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format)
s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format)
s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366)
s["%k"] = hr; // hour, range 0 to 23 (24h format)
s["%l"] = ir; // hour, range 1 to 12 (12h format)
s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12
s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59
s["%n"] = "\n"; // a newline character
s["%p"] = pm ? "PM" : "AM";
s["%P"] = pm ? "pm" : "am";
// FIXME: %r : the time in am/pm notation %I:%M:%S %p
// FIXME: %R : the time in 24-hour notation %H:%M
s["%s"] = Math.floor(self.getTime() / 1000);
s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59
s["%t"] = "\t"; // a tab character
// FIXME: %T : the time in 24-hour notation (%H:%M:%S)
s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn;
s["%u"] = w + 1; // the day of the week (range 1 to 7, 1 = MON)
s["%w"] = w; // the day of the week (range 0 to 6, 0 = SUN)
// FIXME: %x : preferred date representation for the current locale without the time
// FIXME: %X : preferred time representation for the current locale without the date
s["%y"] = ('' + y).length==4 ? ('' + y).substr(2, 2) : (''+y).length==2 ? y : '0'+y ; // year without the century (range 00 to 99)
s["%Y"] = y; // year with the century
s["%%"] = "%"; // a literal '%' character
var re = /%./g;
if (!is_ie5 && !is_khtml)
return str.replace(re, function (par) { return s[par] || par; });
var a = str.match(re);
for (var i = 0; i < a.length; i++) {
var tmp = s[a[i]];
if (tmp) {
re = new RegExp(a[i], 'g');
str = str.replace(re, tmp);
}
}
return str;
};
})();
还有一段是本地化的一些文字(必须2段一起使用):
datetext._DN = new Array
("\u661F\u671F\u65e5",
"\u661F\u671F\u4e00",
"\u661F\u671F\u4e8c",
"\u661F\u671F\u4e09",
"\u661F\u671F\u56db",
"\u661F\u671F\u4e94",
"\u661F\u671F\u516d",
"\u661F\u671F\u65e5");
// Please note that the following array of short day names (and the same goes
// for short month names, _SMN) isn't absolutely necessary. We give it here
// for exemplification on how one can customize the short day names, but if
// they are simply the first N letters of the full name you can simply say:
//
// datetext._SDN_len = N; // short day name length
// datetext._SMN_len = N; // short month name length
//
// If N = 3 then this is not needed either since we assume a value of 3 if not
// present, to be compatible with translation files that were written before
// this feature.
// short day names
datetext._SDN = new Array
("\u65e5",
"\u4e00",
"\u4e8c",
"\u4e09",
"\u56db",
"\u4e94",
"\u516d",
"\u65e5");
// full month names
datetext._MN = new Array
("\u4e00\u6708",
"\u4e8c\u6708",
"\u4e09\u6708",
"\u56db\u6708",
"\u4e94\u6708",
"\u516d\u6708",
"\u4e03\u6708",
"\u516b\u6708",
"\u4e5d\u6708",
"\u5341\u6708",
"\u5341\u4e00\u6708",
"\u5341\u4e8c\u6708");
// short month names
datetext._SMN = new Array
("\u4e00\u6708",
"\u4e8c\u6708",
"\u4e09\u6708",
"\u56db\u6708",
"\u4e94\u6708",
"\u516d\u6708",
"\u4e03\u6708",
"\u516b\u6708",
"\u4e5d\u6708",
"\u5341\u6708",
"\u5341\u4e00\u6708",
"\u5341\u4e8c\u6708");