位置:海鸟网 > IT > JavaScript >

javascript中根据表达式实现字符串格式化为日期——升级版

  实际上我曾经在我的Blog中谈到过这个功能(查看原文),但当时并未做详细的解释,代码亦写得比较拙劣,这段时间又翻起了这段代码,觉得还是有很大改进的余地,于是觉得把代码再行精简一下。

  这次改进的主要有几个地方:

  将日期表达式转换为取数字正则的代码,原来的代码写得非常之业余,我们可以对比一下两次代码:

  原来的代码:

pattern = format.replace("yyyy", "(~1{4})").replace("yy", "(~1{2})")

     .replace("MM", "(~1{2})").replace("M", "(~1{1,2})")

     .replace("dd", "(~1{2})").replace("d", "(~1{1,2})").replace(/~1/g, "d");

  新的代码:

pattern = format.replace(/(yyyy)/g, "([0-9]{4})")

.replace(/(yy)|(MM)|(dd)|(hh)|(mm)|(ss)/g, "([0-9]{2})")

.replace(/[Mdhms]/g, "([0-9]{1,2})");


  对比这两次代码,后面的代码可读性更强,漂亮了许多。

  把获取索引的代码进行了改进

var yPos = format.indexOf("yyyy");

var mPos = format.indexOf("MM");

var dPos = format.indexOf("dd");

var hPos = format.indexOf("hh");

var miPos = format.indexOf("mm");

var sPos = format.indexOf("ss");

if (mPos == -1) mPos = format.indexOf("M");

if (yPos == -1) yPos = format.indexOf("yy");

if (dPos == -1) dPos = format.indexOf("d");

if (hPos == -1) hPos = format.indexOf("h");

if (miPos == -1) miPos = format.indexOf("m");

if (sPos == -1) sPos = format.indexOf("s");


  新的代码:

//获取子表达式的索引

getIndex = function(expr1, expr2) {

var index = format.indexOf(expr1);

if (index == -1) index = format.indexOf(expr2);

return index;

}


var yPos = getIndex("yyyy", "yy");

var mPos = getIndex("MM", "M");

var dPos = getIndex("dd", "d");

var hPos = getIndex("hh", "h");

var miPos = getIndex("mm", "m");

var sPos = getIndex("ss", "s");


  新的代码进行了提取封装,可维护性更强

  还有其它的改进就不说了,读者自己看,对比一下两者的差异。

  最终新代码:

//将字符串转换为日期

String.prototype.toDate = function(format) {

pattern = format.replace(/(yyyy)/g, "([0-9]{4})")

.replace(/(yy)|(MM)|(dd)|(hh)|(mm)|(ss)/g, "([0-9]{2})")

.replace(/[Mdhms]/g, "([0-9]{1,2})");


//获取子表达式的索引

getIndex = function(expr1, expr2) {

var index = format.indexOf(expr1);

if (index == -1) index = format.indexOf(expr2);

return index;

}


var today = new Date();

var returnDate;

if (new RegExp(pattern).test(this)) {

var yPos = getIndex("yyyy", "yy");

var mPos = getIndex("MM", "M");

var dPos = getIndex("dd", "d");

var hPos = getIndex("hh", "h");

var miPos = getIndex("mm", "m");

var sPos = getIndex("ss", "s");

var data = { y: 0, m: 0, d: 0, h: 0, mi: 0, s: 0 };

//对索引进行排序

var pos = new Array(yPos + ",y", mPos + ",m", dPos + ",d", hPos +

",h", miPos + ",mi", sPos + ",s").sort(

function(a, b) {

a = parseInt(a.split(",")[0]);

b = parseInt(b.split(",")[0]);

return a > b;

}

);


//删除索引为-1的数组

var tmpIndex = 0;

var newPos = new Array();

for (var i = 0; i < pos.length; i++) {

if (parseInt(pos[i].split(",")[0]) != -1) {

newPos[tmpIndex] = pos[i];

tmpIndex++;

}

}


//与当前文本进行匹配

var m = this.match(pattern);

for (var i = 1; i < m.length; i++) {


if (i == 0) return;

var flag = newPos[i - 1].split(',')[1];

data[flag] = m[i];

};


data.y = data.y || today.getFullYear();             //年如果为空,则取当前年

data.d = data.d || today.getDate();                 //天如果为空,则取今天

//月不需要处理,因为月的0月是1月


//如果年是yy格式,则加上20

if (data.y.toString().length == 2) data.y = parseInt('20' + data.y);

data.m -= 1;

returnDate = new Date(data.y, data.m, data.d, data.h, data.mi, data.s);

}

returnDate = returnDate || today;

return returnDate;

}


document.writeln("

<pre>测试结果");

document.writeln("10月18日2008年 10点11分12秒".toDate("MM月dd日yyyy年 hh点mm分ss秒"));

document.writeln("2008-10-8".toDate("yyyy-M-d")); //2008年10月8号

document.writeln("12-18 2008".toDate("MM-dd yyyy")); //2008年12月18号

document.writeln("12-16".toDate("MM-dd")); //2009年12月16号

document.writeln("</pre>");

  旧代码:

//将字符串转换为日期

String.prototype.toDate = function(format) {

pattern = format.replace("yyyy", "(~1{4})").replace("yy", "(~1{2})") //年

.replace("MM", "(~1{2})").replace("M", "(~1{1,2})") //月

.replace("dd", "(~1{2})").replace("d", "(~1{1,2})") //日

.replace("hh", "(~1{2})").replace("h", "(~1{1,2})") //时

.replace("mm", "(~1{2})").replace("m", "(~1{1,2})") //分

.replace("ss", "(~1{2})").replace("s", "(~1{1,2})") //称

.replace(/~1/g, "d").replace(" ", "[s]");

sortDate = function(a, b) {

a = parseInt(a.split(",")[0]);

b = parseInt(b.split(",")[0]);

return a > b;

}

var returnDate;

if (new RegExp(pattern).test(this)) {

var yPos = format.indexOf("yyyy");

var mPos = format.indexOf("MM");

var dPos = format.indexOf("dd");

var hPos = format.indexOf("hh");

var miPos = format.indexOf("mm");

var sPos = format.indexOf("ss");

if (mPos == -1) mPos = format.indexOf("M");

if (yPos == -1) yPos = format.indexOf("yy");

if (dPos == -1) dPos = format.indexOf("d");

if (hPos == -1) hPos = format.indexOf("h");

if (miPos == -1) miPos = format.indexOf("m");

if (sPos == -1) sPos = format.indexOf("s");

var pos = new Array(yPos + ",y", mPos + ",m", dPos + ",d", hPos +

",h", miPos + ",mi", sPos + ",s").sort(sortDate);

var tmpIndex = 0;

for (var i = 0; i < pos.length; i++) {

if (pos[i].indexOf('-1') < 0) break;

tmpIndex++;

}

pos = pos.splice(tmpIndex, pos.length - tmpIndex);

var data = { y: 0, m: 0, d: 0, h: 0, mi: 0, s: 0 };

var m = this.match(pattern);

for (var i = 1; i < m.length; i++) {

if (i == 0) return;

var flag = pos[i - 1].split(',')[1];

data[flag] = m[i];

};

if (data.y.toString().length == 2) {

data.y = parseInt('20' + data.y);

}

data.m = data.m - 1;

returnDate = new Date(data.y, data.m, data.d, data.h, data.mi, data.s);

}

if (returnDate == null || isNaN(returnDate)) returnDate = new Date();

return returnDate;

}