在js中经常会用到Date类,但是Date与字符串互相转换的工作实在是太繁琐,有的根本就不是我想要的结果。现在正在学js的正则表达式,刚好把学到的一点应用了起来,并写了一个类DateParser,此类可以将字符串和Date按照指定的format进行格式化转换。具体的js代码及测试htm见下面:
<HTML>
<HEAD>
<script src="QKDateParser.js" type="text/javascript"></script>

<script>...
var parser = null;
function launchParse()

...{
var dfs = document.getElementsByName("DFS");
for(var i=0;i<dfs.length;i++)

...{
if (dfs[i].checked)

...{
parser = new DateParser(dfs[i].value);
break;
}
}

if (parser == null) ...{ alert("请先选择需要转换的字符串的日期格式!"); return; }
var tmpDate = parser.parse(document.getElementById("testDate").value);


if (tmpDate == null) ...{ alert("您输入的日期字符串的格式不正确!"); return; }
document.getElementById("result").value = tmpDate.toString();
document.getElementById("paramList").innerText = parser.toString();
}
function launchReverseParse()

...{
if (parser == null) return;
document.getElementById("result").value += " " + parser.toDateString("yyyy年MM月dd日 HH:时mm:分:ss秒 M-d-yyyy+H:m:s");
}
</script>
</HEAD>
<BODY style="font-size:9pt;">
<FIELDSET style="padding:3px 3px 3px 3px;"><LEGEND>日期解析类DateParser测试(其中秒可忽略)</LEGEND>
<input type="radio" name="DFS" id="dfs0" value="y+M+d"><label for="dfs0">yyyy-MM-dd,日期分隔符可以为".","/","-"(ex:1981/01/29 or 1981.1.29)</label><br/>
<input type="radio" name="DFS" id="dfs1" value="M+d+y"><label for="dfs1">MM-dd-yyyy,日期分隔符可以为".","/","-"(ex:01/29/1981 or 1.29.1981)</label><br/>
<input type="radio" name="DFS" id="dfs2" value="d+M+y"><label for="dfs2">dd-MM-yyyy,日期分隔符可以为".","/","-"(ex:29/01/1981 or 29.1.1981)</label><br/>
<input type="radio" name="DFS" id="dfs3" value="y+M+d H+m+s"><label for="dfs3">yyyy-MM-dd HH:mm:ss,日期分隔符可以为".","/","-"(ex:1981/01/29 05:23:19)</label><br/>
<input type="radio" name="DFS" id="dfs4" value="M+d+y H+m+s"><label for="dfs4">MM-dd-yyyy HH:mm:ss,日期分隔符可以为".","/","-"(ex:01/29/1981 05:23:19)</label><br/>
<input type="radio" name="DFS" id="dfs5" value="d+M+y H+m+s"><label for="dfs5">dd-MM-yyyy HH:mm:ss,日期分隔符可以为".","/","-"(ex:29/01/1981 05:23:19)</label><br/>
<input type="radio" name="DFS" id="dfs6" value="y年M月d日 H时m分s秒"><label for="dfs6">yyyy年MM月dd日 HH时mm分ss秒(ex:1981年01月29日 05时23分19秒)</label><br/>
<input type="radio" name="DFS" id="dfs7" value="M月d日y年 H时m分s秒"><label for="dfs7">MM月dd日yyyy年 HH时mm分ss秒(ex:01月29日1981年 05时23分19秒)</label><br/>
<input type="radio" name="DFS" id="dfs8" value="d日M月y年 H时m分s秒"><label for="dfs8">dd日MM月yyyy年 HH时mm分ss秒(ex:29日01月1981年 05时23分19秒)</label><br/>
<hr size="1px" />
请输入日期字符串:<input type="text" id="testDate"><input type="button" onclick="launchParse();" value="解析转换为日期"> <input type="button" onclick="launchReverseParse();" value="解析转换为字符串"><br/>
<div>解析转换结果输出:</div><textarea id="result" rows="8" cols="50"></textarea><br/>
<span id="paramList"></span>
</FIELDSET>
</BODY>
</HTML>
QKDateParser.js代码:

/**//*============================================================*
| DateParser类 |
| 此类用来解析日期格式的字符串并转换为Date实例;也可以将Date |
| 转换为指定的日期字符串。 |
| |
| 你可以将此js任意复制,或应用到你的项目,网站中。但请保留类 |
| 的相关说明和作者信息,谢谢!也欢迎你反馈建议给我。目的也是 |
| 将更好的代码奉献给各位程序员,好东西就要共享出来,总之: |
| |
| 大家好才是真的好:) |
| 版本:1.0 |
| 作者:QK |
| Email:akaidoor@tom.com |
| Tech blog:http://blog.youkuaiyun.com/aquadp |
| 创建日期:2008-05-08 |
*============================================================*/


/**//*
日期格式模板样式类
此类支持日期以及日期+时间,虽然此类基本可以解析某字符串是否是对应的日期格式,
但是没有加入月对应的天数的判断,此判断功能是在DateParser类中完成。
*/

var DateFormatStyle = ...{"y+M+d":/^d...{4}(-|/|.)(0?[1-9]|1[0-2])1(0?[1-9]|[12]d|3[01])$/,

"M+d+y":/^(0?[1-9]|1[0-2])(-|/|.)(0?[1-9]|[12]d|3[01])2d...{4}$/,

"d+M+y":/^(0?[1-9]|[12]d|3[01])(-|/|.)(0?[1-9]|1[0-2])2d...{4}$/,

"y+M+d H+m+s":/^d...{4}(-|/|.)(0?[1-9]|1[0-2])1(0?[1-9]|[12]d|3[01]) (0?d|1d|2[0-3])(:(0?d|[0-5]d))...{1,2}$/,

"M+d+y H+m+s":/^(0?[1-9]|1[0-2])(-|/|.)(0?[1-9]|[12]d|3[01])2d...{4} (0?d|1d|2[0-3])(:(0?d|[0-5]d))...{1,2}$/,

"d+M+y H+m+s":/^(0?[1-9]|[12]d|3[01])(-|/|.)(0?[1-9]|1[0-2])2d...{4} (0?d|1d|2[0-3])(:(0?d|[0-5]d))...{1,2}$/,

"y年M月d日 H时m分s秒":/^d...{4}年(0?[1-9]|1[0-2])月(0?[1-9]|[12]d|3[01])日 (0?d|1d|2[0-3])时(0?d|[0-5]d)分((0?d|[0-5]d)秒)?$/,

"M月d日y年 H时m分s秒":/^(0?[1-9]|1[0-2])月(0?[1-9]|[12]d|3[01])日d...{4}年 (0?d|1d|2[0-3])时(0?d|[0-5]d)分((0?d|[0-5]d)秒)?$/,

"d日M月y年 H时m分s秒":/^(0?[1-9]|[12]d|3[01])日(0?[1-9]|1[0-2])月d...{4}年 (0?d|1d|2[0-3])时(0?d|[0-5]d)分((0?d|[0-5]d)秒)?$/
};

/**//* 日期格式字符串以及格式模板的分隔符的正则表达式*/
var DateStringDelimiter = /(-|/|.| |年|月|日|:|时|分|秒|+)/;


/**//* 含有31天的月份 */
var MonthOf31Days = [1,3,5,7,8,10,12];


/**//* 含有30天的月份 */
var MonthOf30Days = [4,6,9,11];

/**//*
DateParser构造函数,参数为模板样式类的属性名
如果参数名传入有错误则默认选择第一个格式
*/
function DateParser(formatStyle)

...{
if (formatStyle == undefined || DateFormatStyle[formatStyle] == undefined)
formatStyle = "y+M+d";
this.formatStyle = formatStyle;
this.dateFormatRegex = DateFormatStyle[formatStyle];
this.originDate = null;
}

/**//* 如果输入的日期字符串合法则解析并返回对应的日期 */
DateParser.prototype.parse = function(s)

...{
if (!this.isDateString(s)) this.originDate = null; //当前参数不是日期格式字符串则返回null
return this.originDate;
}


/**//* Date转换为指定格式的日期字符串 */
DateParser.prototype.toDateString = function(format)

...{
return this.originDate.toDateString(format);
}


/**//* 检测输入的日期字符串是否合法 */
DateParser.prototype.isDateString = function(s)

...{
// 检测是否是对应的日期格式
if (!this.dateFormatRegex.test(s)) return false;
// 将解析额日期字符串以及对应的格式模板进行分隔来取得对应的年月日时分秒的值
var arrString = s.split(DateStringDelimiter);
var arrPattern = this.formatStyle.split(DateStringDelimiter);
// 如果解析的日期字符串不包含秒,则默认填充0
if (arrPattern.length == arrString.length + 1) arrString[arrPattern.length-1] = "0";

var year = month = day = hour = minute = second = 0;
for(var i=0;i<arrPattern.length;i++)

...{
var n = arrString[i].trimStartZero();
if (n != "") n = parseInt(n); else n = 0;
if (arrPattern[i] == "y") year = n; //年
if (arrPattern[i] == "M") month = n; //月
if (arrPattern[i] == "d") day = n; //日
if (arrPattern[i] == "H") hour = n; //时
if (arrPattern[i] == "m") minute = n; //分
if (arrPattern[i] == "s") second = n; //秒
}
// 判断输入的年份,月份,和天数是否合理
if (MonthOf31Days.indexOf(month) >= 0 && day > 31) return false;
if (MonthOf30Days.indexOf(month) >= 0 && day > 30) return false;
if (month == 2 && day > 28 + (year.isLeapYear() ? 1 : 0)) return false;
this.originDate = new Date(year,month-1,day,hour,minute,second);
return true;
}


/**//* 返回DateParser当前实例的设置信息 */
DateParser.prototype.toString = function()

...{
var info = "当前设置的日期格式:"+this.formatStyle+" ";
info += "----------------------------------------- ";
info += "可供设置的日期格式参数如下: ";
for(key in DateFormatStyle)

...{
info += key+" ";
}
return info;
}


/**//* 转换Date为指定格式的日期字符串 */
Date.prototype.toDateString = function(format)

...{
if (this == null) return "";
if (typeof(format) != "string") return this.toString();

format = format.replace(/yyyy/g, this.getFullYear().toString());
format = format.replace(/MM/g, (this.getMonth()+1).toString().fillStartZero(2));
format = format.replace(/dd/g, this.getDate().toString().fillStartZero(2));
format = format.replace(/M/g, (this.getMonth()+1).toString());
format = format.replace(/d/g, this.getDate().toString());
format = format.replace(/HH/g, this.getHours().toString().fillStartZero(2));
format = format.replace(/mm/g, this.getMinutes().toString().fillStartZero(2));
format = format.replace(/ss/g, this.getSeconds().toString().fillStartZero(2));
format = format.replace(/H/g, this.getHours().toString());
format = format.replace(/m/g, this.getMinutes().toString());
format = format.replace(/s/g, this.getSeconds().toString());
return format;
}


/**//* 判断是否是闰年 */
Number.prototype.isLeapYear = function()

...{
//年份能被4整除但不能被100整除或者年份能被400整除
return ((0 == this % 4 && 0 != this % 100) || 0 == this % 400);
}


/**//* 替换掉字符串前面的0 */
String.prototype.trimStartZero = function()

...{
return this.replace(/^0*/g, "");
}


/**//* 在字符串前面填充字符0直到使字符串长度为maxLength */
String.prototype.fillStartZero = function(maxLength)

...{
var result = this;
for(var i=0;i<maxLength-this.length;i++)

...{
result = "0"+result;
}
return result;
}


/**//* 判断数组中是否包含对象val,返回所在的数组索引号 */
Array.prototype.indexOf = function(val)

...{
for(var i=0;i<this.length;i++)
if (this[i] == val) return i;
return -1;
}
上面的文件中每个函数都有非常详细的注释,在这里不再做说明。如果有疑问或问题请告诉我。如果你有更好的方法或正则表达式方面的讨论请给我message!









































































































































































































































































