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

一、什么是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 (本篇完)

如果您觉得本文的内容有趣就扫一下吧!捐赠互勉!
??

一起Polyfill系列:让Date识别ISO 8601日期时间格式,布布扣,bubuko.com

时间: 2024-12-05 01:49:20

一起Polyfill系列:让Date识别ISO 8601日期时间格式的相关文章

Eclipse 修改注释的 date time 日期时间格式,即${date}变量格式

Eclipse 修改注释的 date time 日期时间格式,即${date}变量格式 找到eclipse安装目录下面的plugins目录,搜索 org.eclipse.text ,找到一个jar包, 例如我找到的jar包为:org.eclipse.text_3.5.300.v20130515-1451.jar 然后打开它,找到这个类: org.eclipse.jface.text.templates.GlobalTemplateVariables 我们重写这个类就行了.(可反编译,也可以找到源

DATE,DATETIME,DATETIME2等日期时间数据类型

日期范围广 0001-01-01 到 9999-12-31.时间范围广 00:00:00 到 23:59:59.9999999. -----------------DATE --只存储日期 select cast('2016-10-13 12:23:30' as date) --输出结果:2016-10-13 -----------------TIME select cast('2016-10-13 12:23:30' as TIME) --只存储时间 --输出结果:12:23:30.00000

技术杂记-日期时间字符串解析识别

日期时间的格式可谓千奇百怪,做数据汇集相关项目时就会需要识别各种日期时间格式(因为数据来源广泛不可控),然后转换为标准格式或Date类型. 我之前看到同事的一个时间解析方法,当时觉得已经很不错了,后来网上搜索发现这个方法在搜索结果中多次出现,来源就不清楚.我是因项目需要更精确的识别日期时间字符串,于是我慢慢改进原来的方法,以下就是改进后的方法,java语言实现,只要看懂逻辑,应该很容易翻译成其他语言. 1 /** 2 * 解析大部分常见日期格式 <br/> 3 * @param dateStr

Java日期时间(Date/Time)

获取当前日期和时间 在Java中容易得到当前的日期和时间.可以使用一个简单的Date对象的toString()方法,如下所示打印当前日期和时间: import java.util.Date; public class DateDemo { public static void main(String args[]) { // Instantiate a Date object Date date = new Date(); // display time and date using toStr

Java日期的格式String类型GMT,GST换算成日期Date种类

请尊重他人的劳动成果.转载请注明出处:Java日期格式化之将String类型的GMT,GST日期转换成Date类型 http://blog.csdn.net/fengyuzhengfan/article/details/40164721 在实际开发过程中常常会须要将Date类型的数据封装成XML或Json格式在网络上进行传输,另外在将Date类型的数据存到Sqlite数据库中后再取出来的时候仅仅能获取String类型的日期了,这是由于SQLite是无类型的.这样不得不面对将String 类型的日

包装类、Date类、SimpleDateFormat类(基本数据类型&lt;--&gt;String&lt;--&gt;日期/时间)

基本数据类型-->String "+"字符串连接符 基本数据类型<--String 基本数据类型 包装类 String-->xxx xxx parseXxx(String s) byte  Byte byte parseByte(String s) short   Short short parseShort(String s) int  Integer int parseInt(String s) long Long long parseLong(String s)

Java时间格式字符串与Date的相互转化

目录 将Date转化为格式化字符串 时间格式字符串转化为Date @ 将Date转化为格式化字符串 将Date转化为格式化字符串是利用SimpleDateFormat类继承自 java.text.DateFormat类的format方法实现的: public final String format(Date date):将日期格式化成日期/时间字符串. //获取当前时间 Date date = new Date(); //定义转化为字符串的日期格式 SimpleDateFormat sdf =

atitit.日期,星期,时候的显示方法ISO 8601标准

1. ISO 86011 2. DAte日期的显示1 2.1. Normal1 2.2. 顺序日期表示法(可以将一年内的天数直接表示)1 2.3. 星期显示法(可以用2位数表示年内第几个日历星期,再加上一位数表示日历星期内第几天)2 3. 时间表示法(对UTC时间最后加一个大写字母Z,其他时区用实际时间加时差表示)2 4. 日期和时间的组合表示法(要在时间前面加一大写字母T)2 5. 时间段表示法3 5.1. 重复时间表示法3 1. ISO 8601 国际标准化组织的国际标准ISO 8601是日

日期和时间格式(ISO 8601)

参考 ISO 8601 - Wikipedia ISO 8601 Date and time format 原文地址:https://www.cnblogs.com/jffun-blog/p/10217667.html