论坛首页 Web前端技术论坛

javascript格式化日期

浏览 3087 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-03-05   最后修改:2010-03-05
   对日期型数据进行格式化是我们经常遇到的一个问题,但是javascript中并没有提供对日期进行格式化的函数,所以在网上就出现了很多版本的格式化函数,写法不尽相同,但基本都可以达到所需的目标。我这里也写出了一个类似功能的函数,一来巩固一下所学的javascript知识,也可以给大家提供一个参考。
    下面是这个函数的主体实现部分:
    /**
 * 对日期进行格式化,
 * @param date 要格式化的日期
 * @param pattern 进行格式化的模式
 *     支持的模式字母有:
 *     y:年,
 *     M:年中的月份(1-12),
 *     d:月份中的天(1-31),
 *     H:小时(0-23),
 *     h:小时(0-12),
 *     m:分(0-59),
 *     s:秒(0-59),
 *     S:毫秒(0-999),
 *     E:星期(以汉语表示),
 *     e:星期(以英文表示),
 *     A:上午/下午标识,
 *     a:AM/PM标识
 * @return
 */
function formatDate(date,pattern){
	var d;
	if((d=parseDate(date))==null){
		return "";
	}
	if(!pattern){
		pattern = "yyyy-MM-dd";
	}
	var arrWeek = ["星期日","星期一","星期二","星期三","星期四","星期五","星期六","Sunday","Monday","Tuesday","Tuesday","Thursday","Friday","Saturday"];
	var value = new Object();
	value["y"] = parseString(date.getFullYear());
	value["M"] = parseString(date.getMonth() + 1);
	value["d"] = parseString(date.getDate());
	value["H"] = parseString(date.getHours());
	value["h"] = parseString(value["H"] > 12 ? (value["H"]-12) : value["H"]);
	value["m"] = parseString(date.getMinutes());
	value["s"] = parseString(date.getSeconds());
	value["S"] = parseString(date.getMilliseconds());
	value["E"] = arrWeek[date.getDay()];
	value["e"] = arrWeek[date.getDay() + 7];
	value["a"] = (value["H"] > 12 ? "PM" : "AM");
	value["A"] = (value["H"] > 12 ? "下午" : "上午");
	var result = "";
	var i = 0;
	var hasE = false;//是否出现过星期
	var hasAMPM = false;//是否出现过上午下午
	while(i < pattern.length){
		var c = pattern.charAt(i++);
		var lc = c;//记录本次要处理的字母,如'y'
		var tmpStr = c;//本次在处理的字母格式,如'yyyy'
		while(i < pattern.length && (c=pattern.charAt(i))==lc){
			tmpStr += c;
			i++;
		}
		if(value[lc]!=""&&value[lc]!=null&&value[lc]!="undefined"){
			//本次要处理的字母是模式母
			if((lc == "E" || lc == "e") && !hasE){
				//星期
				result += value[lc];
				hasE = true;
			} else if(lc == "E" || lc == "e") {
				result += tmpStr;
			} else if((lc=="a" || lc == "A")  && !hasAMPM){
				//上下午
			    result += value[lc];
				hasAMPM = true;
			} else if((lc=="a" || lc == "A") ){
			    result += tmpStr;
			} else {
				//如果是 单个的日期,月份,小时,分,秒的字符串,不能再进行字符串的截取操作
			    if(tmpStr == "d" || tmpStr == "M" || tmpStr=="H" || tmpStr=="h" || tmpStr == "m" || tmpStr == "s"){
					result += value[lc];
				} else {
					result += value[lc].fillChar(tmpStr.length);
				}
			}
		} else {//非模式字母,直接输出
		    result += tmpStr;
		}
	}
	return result;
}

    先来看一下它能给我们带来什么样的效果吧,测试的代码如下:
var date = new Date();
document.write(formatDate(date,"yyyy-MM-dd HH:mm:ss.SSS E") + "<br>");
document.write(formatDate(date,"yyyy年MM月dd日 HH时mm分ss秒 E") + "<br>");
document.write(formatDate(date,"yyyy-M-d hh:mm:ss.SSS A E") + "<br>");
document.write(formatDate(date,"MM/dd/yy hh:mm:ss a e") + "<br>");
document.write(formatDate(date,"M/d/yyyy") + "<br>");
document.write(formatDate(date,"yyyyyy年MMMMMMM月ddddddd日 HH时mm分ss秒 EEEEE") + "<br>");[color=red]最后这个有点变态了,看它会出现什么结果[/color]
??为什么这里不能显示为红色呢

测试输出为:
2010-10-07 17:08:34.187 星期四
2010年10月07日 17时08分34秒 星期四
2010-10-7 05:08:34.187 下午 星期四
10/07/10 05:08:34 PM Thursday
10/7/2010
002010年0000010月0000007日 17时23分41秒 星期四

    完成上面的测试之后,发现这个函数已经可以较好地为我们提供所需的功能了。这里所采用的模式字母主要参照java中的模式字母,但是只实现其中一部分的模式字母功能。函数中的代码已经尽可能地增加了注释,为以后的再修改及大家的参考提供方便。
     在上面的函数中,用到了几个功能函数,下面是它们的代码清单。其中,前两个函数比较简单,相信很多人也都对这种功能不莫生;后面的fillChar函数类似于oracle中的lpad与rpad函数,但也可以进行字符串的截取操作。上面的对年份进行截取采用的就是fillChar函数;测试中的那个比较变态的格式串采用的就是它的lpad与rpad的功能。
function parseDate(value) {
	var date = null;
	if (Date.prototype.isPrototypeOf(value)) {
		date = value;
	} else if (typeof (value) == "string") {
		date = new Date(value.replace(/-/g, "/"));
	} else if (value != null && value.getTime) {
		date = new Date(value.getTime());
	}
	;
	return date;
};

/**
 * 将对象转换为字符串类型
 */
function parseString(value) {
	if (value == null) {
		return "";
	} else {
		return value.toString();
	}
};
String.prototype.fillChar = function(length,mode,char){
	if(!char){
		char = "0";
	}
	if(this.length>length){//比实际想要的长度更大
		if(mode=="after"){//如果是要在后面填充,截取的时候会将会后面的部分截取掉
			return this.substr(0,length);
		} else {//默认截取前一部分的数据
			return this.substr(this.length - length,length);
		}
	}
	var appendStr = "";
	for(var i = 0; i < (length - this.length)/char.length;i++){
		appendStr += char;
	}
	if(mode == "after"){
		return this + appendStr;
	}
	else {
		return appendStr + this;
	}
};

   功能算是实现了,但是做为javascript的初学者,对这样的代码书写格式及代码的效率都难以把握。希望高手看到后能对效率优化及代码优化方面不吝指导。
   发表时间:2010-07-22  
很好的程序算法。学习了。
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics