将 Date对象 转化为指定格式详解 —— 关于Date对象那些事(番外)

在 关于Date对象那些事 一文中的第一节,我们就给出了转换日期指定格式的方法。
但是这个方法中,有些地方对于初学者可能有点费解,尤其是正则部分。此处对其做个详解。

1. 获取当前日期

获取当前日期时间,我们知道通过方法 new Date() 就可以得到,但是获取到是一个标准格式时间 Fri Jan 18 2019 13:56:47 GMT+0800 (中国标准时间)。但通常我们更渴望得到 2019-01-18 13:56:47 或者 2019/01/18 13:56:47 这种格式。

    var d = new Date(); // 获取当前时间
    console.log(d); // Fri Jan 18 2019 14:00:01 GMT+0800 (中国标准时间)
    console.log(typeof d); // "object"

2.获取特定格式的日期猜想

想要通过截取标准格式时间是不太理想的,因为那是一个对象,不好进行字符串操作。即使转串后可以截取到,但总不太靠谱。于是,我们就想通过Data内置对象方法,把年、月、日、小时、分钟、秒,一一取出来,然后做拼接。

    var yy = d.getFullYear(); // 年
    var mm = d.getMonth() + 1; // 月
    var dd = d.getDate(); // 日
    var hh = d.getHours(); // 小时
    var min = d.getMinutes(); // 分钟
    var ss = d.getSeconds(); // 秒
    var qq = Math.floor((d.getMonth() + 3) / 3); // 季度
    var sss = d.getMilliseconds(); // 毫秒

    console.log("当前时间是:",yy + "-" + mm + "-" +  dd + " " + hh + ":" + min + ":" + ss); // 当前时间是: 2019-1-dd 14:10:21
    console.log("当前季度是:",qq); // 当前季度是: 1
    console.log("当前毫秒数是:",sss); // 当前毫秒数是: 366

注意:getMonth()返回的范围是0-11,所以需要累加1.

我们把这个方法封装成一个函数:

    /**
     * formatDate
     * @return {string}
     */
    function formatDate(){
        var yy = d.getFullYear(); // 年
        var mm = d.getMonth() + 1; // 月。
        var dd = d.getDate(); // 日
        var hh = d.getHours(); // 小时
        var min = d.getMinutes(); // 分钟
        var ss = d.getSeconds(); // 秒
        var qq = Math.floor((d.getMonth() + 3) / 3); // 季度
        var sss = d.getMilliseconds(); // 毫秒
        return yy + "-" + mm + "-" +  dd + " " + hh + ":" + min + ":" + ss); 
    }
 // 调用方法
formatDate(); //  2019-1-dd 14:10:21

3. 最终方案及详解

上面的函数确实能重复调用了,但是不过灵活,复用性不强。我们希望能带入参数,用以说明想要指定的日期格式,然后返回对应的日期格式。
这就不得不用上正则相关方法。具体演练过程这里就不说明,我们直接分析下面方案的实现过程。

    /**
     * formatDate方法,将 Date 转化为指定格式的String
     * @param {String} a 指定格式的字符串,例如 "yyyy-M-d h:m:s"
     * @return {String} 匹配指定格式的日期时间字符串
     * 说明:月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字) 
     * 例子:   
     * (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423   
     * (new Date()).Format("yyyy-M-d h:m:s.S")      ==> 2006-7-2 8:9:4.18  
     */
    function formatDate(a){
        var d = new Date();  // 获取当前时间
        // 构造对象o,里面存储当前时间对应的年、月、日、时、分、秒、季度、毫秒参数
        var o = {
            "M+": d.getMonth() + 1,
            "d+": d.getDate(),
            "h+": d.getHours(),
            "m+": d.getMinutes(),
            "s+": d.getSeconds(),
            "q+": Math.floor((d.getMonth() + 3) / 3),
            "S": d.getMilliseconds()
        };
        // 获取年份
        if (/(y+)/.test(a)) a = a.replace(RegExp.$1, (d.getFullYear() + "").substr(4 - RegExp.$1.length));

      // 获取其他
        for (var k in o) {
            if (new RegExp("(" + k + ")").test(a)) a = a.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        }
        return a;
    }
 // 调用方法
console.log(formatDate("yyyy-M-d")); //  2019-1-18

代码说明:

  1. 获取年份部分:
    (1) /(y+)/是一个正则表达式,/(y+)/.test(a) 是判断参数a中是否有一个或多个字符 y,若有,返回true。
    (2) RegExp是一个对象(函数对象),它是一个全局对象。RegExp.$1是全局属性,当执行任意正则表达式匹配操作时,JavaScript会自动更新RegExp上的全局属性。

补充说明:

  1. 关于 RegExp 对象以及它的静态属性 $1可以参考 MDN: RegExp.$1-$9 和 csdn: JavaScript RegExp.$1-$9 属性详解。
  2. 取子串方法语法:substr(start, length)

4. 拓展

Date.prototype.Format = function(a) {
    var o = {
        "M+": this.getMonth() + 1,
        "d+": this.getDate(),
        "h+": this.getHours(),
        "m+": this.getMinutes(),
        "s+": this.getSeconds(),
        "q+": Math.floor((this.getMonth() + 3) / 3),
        "S": this.getMilliseconds()
    };
    if (/(y+)/.test(a)) a = a.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o) {
        if (new RegExp("(" + k + ")").test(a)) a = a.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)))
    }
    return a
};

// 调用方法
console.log(new Date().Format("yy-MM-dd hh:mm:ss"));//19-01-18 15:04:30

你可能感兴趣的:(将 Date对象 转化为指定格式详解 —— 关于Date对象那些事(番外))