一起 Polyfill 系列:让 Date 识别 ISO 8601 日期时间格式

553 阅读4分钟
原文链接: www.cnblogs.com

  1. 2014-12-12T00:00:00.000Z

  4. 2014-12-12T00:00:00.000+08:00

详细说明请参考度娘:http://baike.baidu.com/link?url=Qr7NLClAyUHihOCl1DK6DQL_gMw5rk3euXdiz3zt6M9ORGFS2XBy7LHmcO2ID-iz

   1. 2014-12-12T00:00:00.000Z

 1.  Date.parse({String} datetime) :接收ISO 8061和GMT的日期时间格式字符串(根据格式内容被识别为0时区或其他时区的日期时间),返回入参所表示的0时区日期时间距离1970年1月1日的毫秒数。

   2.  Date.prototype.toISOString() :返回当前Date类型对象0时区的ISO 8061日期时间格式字符串。形如:2014-12-12T00:00:00.000Z

   3.  new Date({String} datetime) :构造函数的入参在ES5中新增接收ISO 8061格式字符串,其实内部就是调用 Date.parse({String} datetime) 进行转换。

   4.  Date.prototype.toJSON() :返回当前Date类型对象0时区的ISO 8061日期时间格式字符串。形如:2014-12-12T00:00:00.000Z。

/**
  * 第一种入参模式:无入参,实例化当前日期时间的Date对象
  */
var date1 = new Date();
 
/**
  * 第二种入参模式:短日期格式字符串入参,实例化当前时区日期时间的Date对象
  */
var date2 = new Date('2014/12/3');
 
/**
  * 第三种入参模式:长日期格式字符串入参,实例化当前时区日期时间的Date对象
  */
var date3 = new Date('Aug 3, 2014');

/**
  * 第四种入参模式:GMT日期格式字符串入参,实例化指定时区日期时间的Date对象
  */
var date4 = new Date('Tue May 25 2014 00:00:00 GMT +0800');

/**
  * 第五种入参模式:GMT日期格式字符串入参,实例化0时区日期时间的Date对象
  */
var date5 = new Date('Tue May 25 2014 00:00:00 GMT');

/**
  * 第六种入参模式:入参依次为年、月、日、时、分、秒和毫秒的数值(其中仅年和月为必填项,日默认值为1,其他默认值为0),实例化当前时区日期时间的Date对象
  */
var date6 = new Date(2014,12,2,1,1,1,1);
// 无论入参是什么,总返回当前时区的GMT日期时间格式的字符串
var dateStr = Date();

     3.1.  Date.parse({String} datetime) :接收GMT的日期时间格式字符串(根据GMT格式内容被识别为0时区或其他时区的日期时间),返回入参所表示的0时区日期时间距离1970年1月1日的毫秒数

     3.2.  Date.UTC(Y,M,d,H,m,s,ms) :设置0时区的日期时间,返回入参所表示的0时区日期时间距离1970年1月1日的毫秒数

    if (!Date.prototype.toISOString){
        var isLeapYear = function(year){
            return (year % 400 === 0) || (year % 4 === 0 && year % 100 !== 0);
        };
        var operHoursAndMinutes = {}; 
        operHoursAndMinutes['+'] = function(minusHours, minusMinutes, year, month, date, hours, minutes, seconds, milliseconds){
            var ret = {};
            minutes -= minusMinutes;
            hours -= minusHours;
            if (minutes < 0){
                hours -= 1;
                minutes += 60;
            }
            if (hours < 0 ){
                --date;
                hours += 24;
                if (date < 0){
                    --month;
                    if (month < 0){
                        --year;
                        month = 11;
                    }
                    if (month % 2 === 0){
                        date += 31;    
                    }
                    else if (month === 1)
                    {
                        date += isLeapYear(year) ? 29 : 28;
                    }
                    else{
                        date += 30;
                    }

                    if (month < 0){
                        --year;
                        month += 12;
                    }
                }
            }

            ret.year = year;
            ret.month = month;
            ret.date = date;
            ret.hours = hours;
            ret.minutes = minutes;
            ret.seconds = seconds;
            ret.milliseconds = milliseconds;

            return ret;
        };
        operHoursAndMinutes['-'] = function(addHours, addMinutes, year, month, date, hours, minutes, seconds, milliseconds){
            var ret = {};

            minutes += addMinutes;
            hours += addHours;
            if (minutes >= 60){
                hours += 1;
                minutes -= 60;
            }
            if (hours >=24){
                ++date;
                hours -= 24;
                var dateOfCurrMonth = month % 2 === 0 ? 31 : (month === 1 ? (isLeapYear(year) ? 29 : 28) : 30);
                if (date >= dateOfCurrMonth){
                    ++month;
                    date -= dateOfCurrMonth;

                    if (month >= 12){
                        ++year;
                        month -= 12;
                    }
                }
            }

            ret.year = year;
            ret.month = month;
            ret.date = date;
            ret.hours = hours;
            ret.minutes = minutes;
            ret.seconds = seconds;
            ret.milliseconds = milliseconds;

            return ret;
        };
        var regExp = new RegExp('^(\\d{4,4})'
                + '-((?:0[123456789]|1[012]))'
                + '-((?:0[123456789]|[12]\\d|3[01]))'
                + 'T'
                + '((?:[01]\\d|2[0123]))'
                + ':([012345]\\d)'
                + ':([012345]\\d)'
                + '(?:.(\\d{3}))?'
                + '(Z|[+-](?:[01]\\d|2[0123]):?[012345]\\d)
); var parseISOString2UTC = function(ISOString){ var ret = {}; var year = Number(RegExp.$1) , month = Number(RegExp.$2) - 1 , date = Number(RegExp.$3) , hours = Number(RegExp.$4) , minutes = Number(RegExp.$5) , seconds = Number(RegExp.$6) , offset = RegExp.$8 , milliseconds; milliseconds = (milliseconds = Number(RegExp.$7), !isNaN(milliseconds) && milliseconds || 0); if (offset === 'Z'){ ret.year = year; ret.month = month; ret.date = date; ret.hours = hours; ret.minutes = minutes; ret.seconds = seconds; ret.milliseconds = milliseconds; } else if (typeof offset !== 'undefined'){ var symbol = offset.charAt(0); var offsetHours = Number(offset.substring(1,3)); var offsetMinutes = Number(offset.substring(offset.length __JJ_GT_JJ__ 5 ? 4 : 3)); ret = operHoursAndMinutes[symbol](offsetHours, offsetMinutes, year, month, date, hours, minutes, seconds, milliseconds); } return ret; }; var _nativeDate = Date; Date = function(Y,M,D,H,m,s,ms){ var ret, len = arguments.length; if (!(this instanceof Date)){ ret = _nativeDate.apply(null, arguments); } else if (len === 1 && typeof arguments[0] === 'string' && regExp.test(arguments[0])){ var tmpRet; try{ tmpRet = parseISOString2UTC(); } catch(e){ console && console.log('Invalid Date'); return void 0; } ret = new _nativeDate(_nativeDate.UTC(tmpRet.year, tmpRet.month, tmpRet.date, tmpRet.hours, tmpRet.minutes, tmpRet.seconds, tmpRet.milliseconds)); } else if (typeof arguments[0] === 'string'){ ret = new _nativeDate(arguments[0]); } else{ ret = len __JJ_GT_JJ__= 7 ? new _nativeDate(Y, M, D, H, m, s, ms) : len __JJ_GT_JJ__= 6 ? new _nativeDate(Y, M, D, H, m, s) : len __JJ_GT_JJ__= 5 ? new _nativeDate(Y, M, D, H, m) : len __JJ_GT_JJ__= 4 ? new _nativeDate(Y, M, D, H) : len __JJ_GT_JJ__= 3 ? new _nativeDate(Y, M, D) : len __JJ_GT_JJ__= 2 ? new _nativeDate(Y, M) : len __JJ_GT_JJ__= 1 ? new _nativeDate(Y) : new _nativeDate(); } return ret; }; Date.prototype = _nativeDate.prototype; Date.prototype.constructor = Date; var _pad = function(num){ if (num __JJ_LT_JJ__ 10){ return '0' + num; } return num; }; var _padMillisecond = function(num){ if (num __JJ_LT_JJ__ 10){ return '00' + num; } else if (num __JJ_LT_JJ__ 100){ return '0' + num; } return num; }; Date.prototype.toISOString = function(){ return [this.getUTCFullYear(), '-', _pad(this.getUTCMonth() + 1), '-', _pad(this.getUTCDate()), 'T' , _pad(this.getUTCHours()), ':', _pad(this.getUTCMinutes()), ':', _pad(this.getUTCSeconds()), '.', _padMillisecond(this.getUTCMilliseconds()), 'Z'].join(''); }; // 复制可枚举的类成员 for (var clsProp in _nativeDate){ if (_nativeDate.hasOwnProperty(clsProp)){ Date[clsProp] = _nativeDate[clsProp]; } } // 复制不可枚举的类成员 var innumerableMems = ['UTC']; for (var i = 0, clsProp; clsProp = innumerableMems[i++];){ Date[clsProp] = _nativeDate[clsProp]; } Date.parse = function(str){ if (['string', 'number'].indexOf(typeof str) === -1) return NaN; var isMatch = regExp.test(str), milliseconds = 0; if (!isMatch) return _nativeDate.parse(str); var tmpRet = parseISOString2UTC(); return _nativeDate.UTC(tmpRet.year, tmpRet.month, tmpRet.date, tmpRet.hours, tmpRet.minutes, tmpRet.seconds, tmpRet.milliseconds); }; Date.now = Date.now || function(){ return +new this(); }; }