JS日期格式化函数性能探底

原文出处:http://yaniswang.com/frontend/2013/02/16/dateformat-performance/

最近开发的软件中需要用到日志功能,其中有一个重要功能是显示日期和时间。于是网上搜了一把,搜到大量的日期格式化函数,不过比较了下,感觉代码都不够优雅,而且性能都不给力。

对线上一些代码进行了评测,结果如下:

测试代码如下,分别对格式化函数进行50万次计算:

 
 
  1. var start = new Date().getTime();
  2. var date = new Date();
  3. for(var i = 0;i<500000;i++){
  4. date.format1('yyyy-MM-dd hh:mm:ss');
  5. }
  6. console.log(new Date().getTime() - start);

函数1:

 
 
  1. // 对Date的扩展,将 Date 转化为指定格式的String
  2. // 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
  3. // 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
  4. // 例子:
  5. // (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
  6. // (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
  7. Date.prototype.format1 = function (fmt) { //author: meizz
  8. var o = {
  9. "M+": this.getMonth() + 1, //月份
  10. "d+": this.getDate(), //日
  11. "h+": this.getHours(), //小时
  12. "m+": this.getMinutes(), //分
  13. "s+": this.getSeconds(), //秒
  14. "q+": Math.floor((this.getMonth() + 3) / 3), //季度
  15. "S": this.getMilliseconds() //毫秒
  16. };
  17. if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
  18. for (var k in o)
  19. if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
  20. return fmt;
  21. }

测试三次:

 
 
  1. 成绩16657毫秒
  2. 成绩26739毫秒
  3. 成绩36747毫秒
  4. 平均:6714毫秒

函数2:

 
 
  1. /** * 对Date的扩展,将 Date 转化为指定格式的String * 月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(q)
  2. 可以用 1-2 个占位符 * 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字) * eg: * (new
  3. Date()).pattern("yyyy-MM-dd hh:mm:ss.S")==> 2006-07-02 08:09:04.423
  4. * (new Date()).pattern("yyyy-MM-dd E HH:mm:ss") ==> 2009-03-10 二 20:09:04
  5. * (new Date()).pattern("yyyy-MM-dd EE hh:mm:ss") ==> 2009-03-10 周二 08:09:04
  6. * (new Date()).pattern("yyyy-MM-dd EEE hh:mm:ss") ==> 2009-03-10 星期二 08:09:04
  7. * (new Date()).pattern("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
  8. */
  9. Date.prototype.format2=function(fmt) {
  10. var o = {
  11. "M+" : this.getMonth()+1, //月份
  12. "d+" : this.getDate(), //日
  13. "h+" : this.getHours()%12 == 0 ? 12 : this.getHours()%12, //小时
  14. "H+" : this.getHours(), //小时
  15. "m+" : this.getMinutes(), //分
  16. "s+" : this.getSeconds(), //秒
  17. "q+" : Math.floor((this.getMonth()+3)/3), //季度
  18. "S" : this.getMilliseconds() //毫秒
  19. };
  20. var week = {
  21. "0" : "/u65e5",
  22. "1" : "/u4e00",
  23. "2" : "/u4e8c",
  24. "3" : "/u4e09",
  25. "4" : "/u56db",
  26. "5" : "/u4e94",
  27. "6" : "/u516d"
  28. };
  29. if(/(y+)/.test(fmt)){
  30. fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
  31. }
  32. if(/(E+)/.test(fmt)){
  33. fmt=fmt.replace(RegExp.$1, ((RegExp.$1.length>1) ? (RegExp.$1.length>2 ? "/u661f/u671f" : "/u5468") : "")+week[this.getDay()+""]);
  34. }
  35. for(var k in o){
  36. if(new RegExp("("+ k +")").test(fmt)){
  37. fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
  38. }
  39. }
  40. return fmt;
  41. }

测试三次:

 
 
  1. 成绩17334毫秒
  2. 成绩27497毫秒
  3. 成绩37498毫秒
  4. 平均:7443毫秒

本着完美主义的态度,自己重新造了个更好的轮子,分享给需要的同学们,代码如下:

 
 
  1. /**
  2. * 对日期进行格式化,
  3. * @param date 要格式化的日期
  4. * @param format 进行格式化的模式字符串
  5. * 支持的模式字母有:
  6. * y:年,
  7. * M:年中的月份(1-12),
  8. * d:月份中的天(1-31),
  9. * h:小时(0-23),
  10. * m:分(0-59),
  11. * s:秒(0-59),
  12. * S:毫秒(0-999),
  13. * q:季度(1-4)
  14. * @return String
  15. * @author yanis.wang@gmail.com
  16. */
  17. function dateFormat(date, format) {
  18. if(format === undefined){
  19. format = date;
  20. date = new Date();
  21. }
  22. var map = {
  23. "M": date.getMonth() + 1, //月份
  24. "d": date.getDate(), //日
  25. "h": date.getHours(), //小时
  26. "m": date.getMinutes(), //分
  27. "s": date.getSeconds(), //秒
  28. "q": Math.floor((date.getMonth() + 3) / 3), //季度
  29. "S": date.getMilliseconds() //毫秒
  30. };
  31. format = format.replace(/([yMdhmsqS])+/g, function(all, t){
  32. var v = map[t];
  33. if(v !== undefined){
  34. if(all.length > 1){
  35. v = '0' + v;
  36. v = v.substr(v.length-2);
  37. }
  38. return v;
  39. }
  40. else if(t === 'y'){
  41. return (date.getFullYear() + '').substr(4 - all.length);
  42. }
  43. return all;
  44. });
  45. return format;
  46. }

使用方法:

 
 
  1. dateFormat('yyyy-MM-dd hh:mm:ss');
  2. dateFormat(new Date(), 'yyyy-MM-dd hh:mm:ss');

测试三次:

 
 
  1. 成绩12903毫秒
  2. 成绩22900毫秒
  3. 成绩32896毫秒
  4. 平均:2899毫秒

经过改造的函数,整体上性能提升明显,从6714毫秒提升到2899毫秒,减少了3815毫秒,整体降到原43%的时间,性能提升一倍以上。并且从原形注入方式改为静态函数方式,更优雅大方。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值