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

转载 2015年07月07日 10:02:53

原文出处: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%的时间,性能提升一倍以上。并且从原形注入方式改为静态函数方式,更优雅大方。

相关文章推荐

js 时间戳 日期格式化 函数

function date ( format, timestamp ) { var a, jsdate=((timestamp) ? new Date(timestamp*1000) : n...

js的日期格式化函数

//--------------------------------------------------------------------------------------------------...

js 格式化时间日期函数小结

Date.prototype.format = function(format){ var o = { "M+" : this.getMonth()+1, //month "d+" : this.ge...

一个js日期格式化函数

函数:格式化日期 参数:formatStr-格式化字符串 d:将日显示为不带前导零的数字,如1 dd:将日显示为带前导零的数字,如01 ddd:将日显示为缩写形式,如Sun dddd:将日显示为全名,...

追猎者:贵金属二次探底未果,本周依然保持逢低做多

现货白银上周;现货黄金上周五最后一个交易日收一根小阴锤形线。周K线收一根实体较小阴线。周内行 情受上周各方面的经济数据影响处于1700-1738区间整理,上周金价未能有效突破1740阻力,但是经过震...

陈怡暖:黄金探底现神针,神针在手天下我有

陈怡暖:黄金探底现神针,神针在手天下我有      陈怡暖:现任中瀚集团首席分析师,毕业于西南财经大学金融系,国外进修金融专业两年,五年从业经验,知名财经频道分析解说师,各大财经网站专业撰...

js操作日期函数

  • 2013年12月05日 13:36
  • 2KB
  • 下载

C++/C语言探底巩固

函数前使用extern没有意义;extern用在变量前表示变量是一个外部链接符号。(函数天然是一个外部链接符号) ——与此相关的,指定函数的调用风格(__cdecl, __stdcall, __fa...

柴俊理金:避险升温黄金受益,原油探底起伏不定

柴俊理金:避险升温黄金受益,原油探底起伏不定      隔夜正当美联储加息预期炒作火热之际,全球市场也暴露出越来越多的问题,日本推迟上调消费税、英国退欧忧虑骤升、中国经济疲弱等因素激发了全球市场的...

关于爱迪生是否说了1%的灵感比99%的汗水重要的探底

2月11日,爱迪生的生日又到了。 他的那句名言谁都知道:“天才是百分之一的灵感,百分之九十九的汗水。” 但是,国内盛传这个名言后面还有一句:“但那1%的灵感是最重要的,甚至比那99%的汗水都要重要...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JS日期格式化函数性能探底
举报原因:
原因补充:

(最多只允许输入30个字)