ISO格式的UTC时间与本地时间的互相转化 |
您所在的位置:网站首页 › iso8601时间格式Z是啥 › ISO格式的UTC时间与本地时间的互相转化 |
最近遇到了这样一个需求,将后端传过来的ISO格式的UTC时间转换成ISO格式的本地时间。 UTC 和 ISO首先,我们先了解一下什么是UTC时间,什么是ISO格式。 协调世界时(英语:Coordinated Universal Time,法语:Temps Universel Coordonné,简称UTC)是最主要的世界时间标准,其以原子时秒长为基础,在时刻上尽量接近于格林尼治标准时间。 —— 维基百科 整个地球分为二十四时区,每个时区都有自己的本地时间,同一时刻每个时区的时间都不一样,所以就用UTC来统一标准的。 国际标准ISO 8601,是国际标准化组织的日期和时间的表示方法,全称为《数据存储和交换形式·信息交换·日期和时间的表示方法》。目前是第三版“ISO8601:2004”以替代第一版“ISO8601:1988”与第二版“ISO8601:2000”。 —— 维基百科 当前的UTC时间是2018-01-02T06:29Z(ISO 8601 表示法。)其中Z是4位数字格式的时间偏移量,不写的时候默认不偏移。 UTC时间转本地时间 第一种方法我们可以在控制台中看一下: new Date() Tue Jan 02 2018 16:42:02 GMT+0800 (CST) new Date('2018-01-02T00:00') Tue Jan 02 2018 00:00:00 GMT+0800 (CST) new Date('2018-01-02T00:00+0800') Tue Jan 02 2018 00:00:00 GMT+0800 (CST) new Date('2018-01-02T00:00-0800') Tue Jan 02 2018 16:00:00 GMT+0800 (CST) new Date('2018-01-02T00:00+0000') Tue Jan 02 2018 08:00:00 GMT+0800 (CST)可以看到, new Date()返回的是当前本地时间。new Date('2018-01-02T00:00') 传入的是ISO格式的字符串,但是没有加偏移量,可以看到结果本地时间跟传入的时间一致,但是上面说其中Z是4位数字格式的时间偏移量,不写的时候默认不偏移, 转化成本地时间不应该是Tue Jan 02 2018 08:00:00 GMT+0800 (CST)吗? 原来new Date()对传入的字符串调用Date.parse()来解析, 如果没有指定时区,默认使用本地时区。 parse 方法接受一个表示时间的字符串,返回相应的时间值。该方法可以接受符合 RFC2822 / IETF 日期语法 (RFC2822 Section 3.3) 的字符串,如 "Mon, 25 Dec 1995 13:30:00 GMT"。该方法能够理解美国大陆时区的缩写,但是为了更通用,应该使用时区偏移,如 "Mon, 25 Dec 1995 13:30:00 +0430" (格林威治的子午线向东偏移4小时30分钟)。如果没有指定时区,默认使用本地时区。—— MDN 后面例子中+0800,-0800,+0000 就更好理解了。 所以, UTC 时间与 本地时间的关系就是: UTC + 时区差 = 本地时间于是,我们只需要知道时区差就可以转换时间了, 可以利用Date.prototype.getTimezoneOffset(): 时区偏差(time-zone offset)表示协调世界时(UTC)与本地时区之间的差值,单位为分钟。需要注意的是如果本地时区晚于协调世界时,则该差值为正值,如果早于协调世界时则为负值。 --MDN var x = new Date(); var currentTimeZoneOffsetInHours = x.getTimezoneOffset() / 60;然后进行简单的加减即可,不过要注意晚于UTC是正,早是负。 第二种方法然而这样就结束了吗? No,还有更简单的方法。 从上面的例子中我们还可以看到, new Date()返回的都是本地时间,所以我们看一下Date.prototype.toString(): Return an implementation-dependent String value that represents tv as a date and time in the current time zone using a convenient, human-readable form. --Standard ECMA-262 可以看到toString返回的时间就是基于系统当前所在时区的,即本地时间,所以直接调用toString即可转化为本地时间: let value = '2018-01-02T00:00+0000' new Date(value).toString()然后再将得到的时间字符串解析成ISO格式: /** * 把 JS datetime 值转为指定日期时间格式 * @param {string} value - Js datetime string * @return {string} - ISO Dates YYYY-MM-DDTHH:mm:ss */ export function getISOdatetime (value) { var tmpStr = new Date(value), year = tmpStr.getFullYear(), month = pad(tmpStr.getMonth() + 1), // 月份取值0-11 date = pad(tmpStr.getDate()), hour = pad(tmpStr.getHours()), minute = pad(tmpStr.getMinutes()), second = pad(tmpStr.getSeconds()) return `${year}-${month}-${date}T${hour}:${minute}:${second}` } /** * 把 UTC时间 转换成 本地时间 * @param {string} value - UTC datetime string * @return {string} - ISO Dates YYYY-MM-DDTHH:mm:ss */ export function getLocalISODatetime (value) { return getISOdatetime(new Date(value).toString()) } 本地时间转UTC时间那本地时间转换成UTC时间也很简单: new Date() //Wed Jan 24 2018 11:06:29 GMT+0800 (CST) new Date().toISOString() // "2018-01-24T03:06:22.861Z"toISOString() 方法返回一个 ISO(ISO 8601 Extended Format)格式的字符串: YYYY-MM-DDTHH:mm:ss.sssZ。时区总是UTC(协调世界时),加一个后缀“Z”标识。 ------ Date.prototype.toISOString() | MDN 哈哈,其实最终的实现很简单,但是要搞清楚原理需要深入了解一下标准是怎么去定义实现的。 参考资料 ISO日期格式标准 Convert UTC date time to local date time 协调世界时 | 维基百科 ISO 8601 | 维基百科 Date.parse() | MDN Date.prototype.getTimezoneOffset() | MDN Date.prototype.toString ( ) | Standard ECMA-262 Date.prototype.toISOString() | MDN |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |