0. 概述

在写一门语言的代码的时候,时间操作往往是一个不可缺少而且又复杂的一项,本文就记录一下 JavaScript 中关于日期时间的一些常见操作。本文的所有操作都基于 Chrome,未在 IE 中测试,需注意。

1. Date 操作

2. 字符串转 Date

2.1 标准 ISO 时间

[[email protected]]# cat date.js
var d = new Date("2015");
var d = new Date("2015-03");
var d = new Date("2015-03-25");
var d = new Date("2015-03-25T12:00:00Z");
var d = new Date("2015-03-25T12:00:00-06:30");

2.2 js 时间格式

[[email protected]]# cat date.js
var d = new Date("03/25/2015");                // JavaScript Short Dates.
var d = new Date("Mar 25 2015");            // JavaScript Long Dates.
var d = new Date("25 Mar 2015");            // 也是 OK
var d = new Date("January 25 2015");    // 也没问题
var d = new Date("JANUARY, 25, 2015");    // 逗号可以忽略

2.3 Date 输入组件

[[email protected]]# cat date.js
var msec = Date.parse("March 21, 2012");
var d = new Date(msec);

2.4 自定义解析格式

[[email protected]]# cat date.js
/**
 * 将字符串解析成日期
 * @param str 输入的日期字符串,如'2014-09-13'
 * @param fmt 字符串格式,默认'yyyy-MM-dd',支持如下:y、M、d、H、m、s、S,不支持w和q
 * @returns 解析后的Date类型日期
 */
function parseDate(str, fmt)
{
    fmt = fmt || 'yyyy-MM-dd';
    var obj = {y: 0, M: 1, d: 0, H: 0, h: 0, m: 0, s: 0, S: 0};
    fmt.replace(/([^yMdHmsS]*?)(([yMdHmsS])\3*)([^yMdHmsS]*?)/g, function(m, $1, $2, $3, $4, idx, old)
    {
        str = str.replace(new RegExp($1+'(\\d{'+$2.length+'})'+$4), function(_m, _$1)
        {
            obj[$3] = parseInt(_$1);
            return '';
        });
        return '';
    });
    obj.M--; // 月份是从0开始的,所以要减去1
    var date = new Date(obj.y, obj.M, obj.d, obj.H, obj.m, obj.s);
    if(obj.S !== 0) date.setMilliseconds(obj.S); // 如果设置了毫秒
    return date;
}

parseDate('2016-08-11'); // Thu Aug 11 2016 00:00:00 GMT+0800
parseDate('2016-08-11 13:28:43', 'yyyy-MM-dd HH:mm:ss') // Thu Aug 11 2016 13:28:43 GMT+0800

3. Date 转字符串

3.1 默认方法

[[email protected]]# cat date.js
var time = 0;
time = new Date(1507601410000);//毫秒转日期格式
console.log("time:"+time);
console.log("time.toDateString():"+time.toDateString());
console.log("time.toJSON():"+time.toJSON());
console.log("time.toUTCString():"+time.toUTCString());
console.log("time.toLocaleDateString():"+time.toLocaleDateString());
console.log("time.toLocaleString():"+time.toLocaleString());
console.log("time.toLocaleTimeString():"+time.toLocaleTimeString());
console.log("time.valueOf():"+time.valueOf());

结果:

[[email protected]]# console
time:Tue Oct 10 2017 10:10:10 GMT+0800 (Hong Kong Standard Time)
VM150:4 time.toDateString():Tue Oct 10 2017
VM150:5 time.toJSON():2017-10-10T02:10:10.000Z
VM150:6 time.toUTCString():Tue, 10 Oct 2017 02:10:10 GMT
VM150:7 time.toLocaleDateString():10/10/2017
VM150:8 time.toLocaleString():10/10/2017, 10:10:10 AM
VM150:9 time.toLocaleTimeString():10:10:10 AM
VM150:10 time.valueOf():1507601410000

3.2 自定义特定格式

[[email protected]]# cat date.js
Date.prototype.addHours = function(h) {
  this.setTime(this.getTime() + (h*60*60*1000));
  return this;
}
Date.prototype.yyyymmdd = function() {
  var mm = this.getMonth() + 1; // getMonth() is zero-based
  var dd = this.getDate();

  return [this.getFullYear(),
          (mm>9 ? '' : '0') + mm,
          (dd>9 ? '' : '0') + dd
         ].join('');
};

var date = new Date();
date.addHours(18);
date.yyyymmdd();

3.3 自定义通用格式

[[email protected]]# cat date.js
<script>
    var time = 0;
    time = new Date(1507601410256);//毫秒转日期格式
    console.log("time:"+time);

    //使用函数的方式进行定义
    function dateFormat(fmt,date){
        var o = {
            "M+" : date.getMonth()+1,                 //月份
            "d+" : date.getDate(),                    //日
            "h+" : date.getHours(),                   //小时
            "m+" : date.getMinutes(),                 //分
            "s+" : date.getSeconds(),                 //秒
            "q+" : Math.floor((date.getMonth()+3)/3), //季度
            "S"  : date.getMilliseconds()             //毫秒
        };
        if(/(y+)/.test(fmt)){
            fmt=fmt.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length));
        }
        for(var k in o)
            if(new RegExp("("+ k +")").test(fmt))
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
        return fmt;
    }

    //使用原型方法的方式定义
    Date.prototype.timeFormat = function(fmt){
        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(fmt)){
            fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
        }
        for(var k in o)
            if(new RegExp("("+ k +")").test(fmt))
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
        return fmt;
    }

    //调用
    console.log("dateFormat():"+dateFormat("MM-dd hh:mm 第q季度",time));
    console.log("dateFormat():"+dateFormat("yyyy-MM-dd hh:mm:s 第q季度",time));
    console.log("dateFormat():"+dateFormat("yyyy年MM月dd日 hh时mm分ss秒S毫秒 第q季度",time));

    console.log("time.timeFormat():"+time.timeFormat("MM-dd hh:mm 第q季度"));
    console.log("time.timeFormat():"+time.timeFormat("yyyy-MM-dd hh:mm:s 第q季度"));
    console.log("time.timeFormat():"+time.timeFormat("yyyy年MM月dd日 hh时mm分ss秒S毫秒 第q季度"));
</script>