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

 2023-09-05 阅读 55 评论 0

摘要:一、什么是ISO 8601日期时间格式 ISO 8601是国际标准化组织制定的日期时间表示规范,全称是《数据存储和交换形式信息交换日期和时间的表示方法》。 示例: 1. 2014-12-12T00:00:00.000Z 2.2014-12-12T00:00:00.000+08 3.2014-12-12T00:00:00.000+0

一、什么是ISO 8601日期时间格式

  ISO 8601是国际标准化组织制定的日期时间表示规范,全称是《数据存储和交换形式·信息交换·日期和时间的表示方法》。

  示例:

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

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

  3. 2014-12-12T00:00:00.000+0800

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

  5. 2004-W17-3

  6. 0001-165

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

 

二、Javascript中实现的ISO 8601日期时间格式

  度娘后大家应该对ISO 8061有一定的了解了吧。ISO 8601的内容十分丰富,可惜Javascript仅仅实现一小部分而已,不过这一部分就够我们用了。

  javascript支持的ISO 8061格式如下:

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

 2. 2014-12-12T00:00:00.000+0800

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

 

二、ES5中涉及ISO 8061日期时间格式的方法

 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。

 

三、认识ES3下的Date类型

   1. 作为构造函数使用



/*** 第一种入参模式:无入参,实例化当前日期时间的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);



   2. 作为函数使用


// 无论入参是什么,总返回当前时区的GMT日期时间格式的字符串
var dateStr = Date();

3. 类成员

     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日的毫秒数

   4. 部分实例成员

  4.1.  Date.prototype.toGMTString() :返回当前Date对象的GMT日期时间格式字符串(仅为了向后兼容而已)

  4.2.  Date.prototype.toUTCString() :返回当前Date对象的GMT日期时间格式字符串(建议使用该方法)



四、一起Polyfill



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 > 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 >= 7 ? new _nativeDate(Y, M, D, H, m, s, ms): len >= 6 ? new _nativeDate(Y, M, D, H, m, s): len >= 5 ? new _nativeDate(Y, M, D, H, m): len >= 4 ? new _nativeDate(Y, M, D, H): len >= 3 ? new _nativeDate(Y, M, D): len >= 2 ? new _nativeDate(Y, M): len >= 1 ? new _nativeDate(Y): new _nativeDate();}return ret;};Date.prototype = _nativeDate.prototype;Date.prototype.constructor = Date;var _pad = function(num){if (num < 10){return '0' + num;}return num;};var _padMillisecond = function(num){if (num < 10){return '00' + num;}else if (num < 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();};}

五、总结

  上述实现相对es5-shim来讲考虑的地方仍有欠缺,这源于我对日期时间格式的理解不够完整,因此请大家多多见谅。

 

原创文章,转载请注明来自^_^肥仔John[http://fsjohnhuang.cnblogs.com]

本文地址:http://www.cnblogs.com/fsjohnhuang/p/3731251.html (本篇完)


版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/1164.html

上一篇:善用meta
下一篇:DP! | 不要怂!

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息