如何使不同时区的时间与京8区一致?(JS实现)

Update:2019/1/28

更简单的是使用这个函数(toDate):

// 自定义日期格式如下(年月日都必须提供):
// "2011-11-11"
// "2011-11-11 11:11"
// "2011-11-11 11:11:11"
const re_custom = /^(\d{4})-(\d{2})-(\d{2})(?: (\d{2}):(\d{2})(?::(\d{2}))?)?$/; // iso8601日期格式见:
// http://www.ecma-international.org/ecma-262/5.1/#sec-15.9
const re_iso8601 = /^(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?T(?:(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?)?Z?$/;
const _toString = Object.prototype.toString; // instanceof Date在跨frame和cypress测试上返回false
function isDate(o) {
return _toString.call(o) === '[object Date]';
} function toDate(input) {
if (!input) {
return new Date();
} else if (isDate(input)) {
return new Date(input);
} else if (typeof input === 'number') {
return new Date(input);
} else if (typeof input === 'string'){
// 如果是自定义的格式,则用本地时间,
// 否则,使用原生的构造方法(本地还是UTC看具体实现)。
let r = re_custom.exec(input);
if (r) {
return new Date(~~r[1], ~~r[2]-1, ~~r[3], ~~r[4], ~~r[5], ~~r[6]);
} r = re_iso8601.exec(input);
if (r) {
// month/date缺省值为1月/1日
let month = ~~r[2] - 1;
if (month < 0) month = 0;
let date = ~~r[3];
if (date === 0) date = 1; return new Date(Date.UTC(~~r[1], month, date, ~~r[4], ~~r[5], ~~r[6], ~~r[7]));
} return new Date(input);
}
}

----------------------------分割线-------------------------------

一般而言,我们都以时间戳的方式存储某个时间。在需要的时候提取出来,根据不同业务需求进行转化:

function transfromDate(time) {
// 假设time是时间戳,如:1514273945276
let curDate = new Data(time);
// todo
}

这里存在一个潜在问题——改变本机的时区,curDate的值会发生变化!shit!!!

当Date作为构造函数调用并传入多个参数时,所定义参数代表的是当地时间

MDN

即,构造出的日期用来显示时,会被转换为本地时间(调用 toString 方法):

>new Date()
<Tue Dec 26 2017 15:47:50 GMT+0800 (中国标准时间)

GMT AND UTC

GMT+0800是个什么东西呢?我们先来介绍一些可能当年在地理课上学习过的基本概念。

以前人们通过观察太阳的位置来决定时间(比如:使用日晷),这就使得不同经纬度的地区时间是不一样的。后来人们进一步规定以子午线为中心,向东西两侧延伸,每 15 度划分一个时区,刚好是 24 个时区。然后因为一天有 24 小时,地球自转一圈是 360 度,360 度 / 24 小时 = 15 度/小时,所以每差一个时区,时间就差一个小时

GMT:

最开始的标准时间(子午线中心处的时间)是英国伦敦的皇家格林威治天文台的标准时间(因为它刚好在本初子午线经过的地方),这就是我们常说的 GMT(Greenwich Mean Time)。

然后其他各个时区根据标准时间确定自己的时间,往东的时区时间早(表示为 GMT+hh:mm)、往西的时区时间晚(表示为 GMT-hh:mm)。比如,中国标准时间是东八区,我们的时间就总是比 GMT 时间早 8 小时,他们在早晨 9 点,我们才凌晨 1 点。

所以,GMT+0800 表示早于格林威治时间8小时。

UTC:

但是GMT其实是根据地球自转、公转计算的(太阳每天经过英国伦敦皇家格林威治天文台的时间为中午 12 点),不是非常准确,于是后面提出了根据原子钟计算的标准时间 UTC(Coordinated Universal Time)。

一般情况下,GMT 和 UTC 可以互换,但是实际上,GMT 是一个时区,而 UTC 是一个时间标准。

JS使不同时区的时间与京8区一致

要计算不同时区相对于京8区的时间偏差,我们要借助 Javascript 中的 Date 对象的实例方法 getTimezoneOffset():

getTimezoneOffset() 方法返回协调世界时(UTC)相对于当前时区的时间差值,单位为分钟。

如果本地时区早于协调世界时(UTC),则该差值为负值,如果晚于协调世界时则为正值


东时区 格林威治 西时区
GMT +/- + -
getTimezoneOffset() < 0 > 0
早/晚

完整代码:

/**
* 获取绝对时间
* 即无论你在哪个时区,得到的时间和京8区的时间一致
*
* @param {Date} time
* @returns {years,month, day, hours, minutes, seconds}
*/
function getAbsTime(time) {
try {
let currentZoneTime = new Date(time);
let currentZoneHours = currentZoneTime.getHours();
let offsetZone = currentZoneTime.getTimezoneOffset() / 60; if(offsetZone > 0) {
// 大于0的是西区(西区晚) 西区应该用时区绝对值加京八区 重新设置时间
// 西区时间比东区时间晚 所以加时区间隔
offsetZone = offsetZone + 8;
currentZoneTime.setHours(currentZoneHours - offsetZone)
} else {
// 小于0的是东区(东区早) 东区时间直接跟京八区相加
offsetZone += 8;
currentZoneTime.setHours(currentZoneHours + offsetZone);
}
return transfromDate(currentZoneTime)
} catch(e) {
throw e
}
}

部分类容节选自:

https://segmentfault.com/a/1190000004292140

https://www.cnblogs.com/liyunhua/p/4661070.html

如何使不同时区的时间与京8区一致?(JS实现)的更多相关文章

  1. 关于时区的时间的详解,比如UTC\GMT等

    UTC 和 GMT 及 北京时间的关系 UTC和GMT,这两者几乎是同一概念.它们都是指的格林尼治标准时间,只不过UTC的称呼更为正式一点.两者的区别在于前者是一个天文 上的概念,而 后者是基于一个原 ...

  2. openerp 常见问题 OpenERP为什么选择了时区后时间还是不对?(转载)

    OpenERP为什么选择了时区后时间还是不对? 原文地址:http://cn.openerp.cn/%E4%B8%BA%E4%BB%80%E4%B9%88%E9%80%89%E6%8B%A9%E4%B ...

  3. Linux系统的时区和时间调整

     linux调整系统时区: 1)tzselect命令 找到相应的时区文件/usr/share/zoneinfo/Asia/Shanghai,用这个文件替换当前的/etc/localtime文件. 或者 ...

  4. 查看修改Linux时区和时间

    查看/修改Linux时区和时间 一.时区 1. 查看当前时区 date -R 2. 修改设置时区 方法(1) tzselect 方法(2) 仅限于RedHat Linux 和 CentOS timec ...

  5. javascript通过时区获取时间

    /* 描述:时区的换算 参数:offset时区位置 使用:东八区calcTime(”+8"); */ function calcTime(offset) { // 创建一个本地日期 var ...

  6. NSDate获取当前时区的时间

    [NSDate date]获取的是GMT时间,要想获得某个时区的时间,以下代码可以解决这个问题 NSDate *date = [NSDate date]; NSTimeZone *zone = [NS ...

  7. centos修改时区,设置时间

    在我们使用CentOS系统的时候,也许时区经常会出现问题,有时候改完之后还是会出错,下面我们就来学习一种方法来改变这个状况.如果没有安装,而你使用的是 CentOS系统 那使用命令 yum insta ...

  8. LINUX更改时区和时间

    因为公司运营海外游戏,服务器也多数放在国外,有时候要求服务器时区和时间要与所服务的地区一致,这里就涉及到更改服务器时区和时间的问题: 下面以一台在美国的服务器为例,我们的IDC提供商是一家德国公司,服 ...

  9. Java 时区之间时间转换

    SimpleDateFormat foo = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); System.out.println(&qu ...

随机推荐

  1. hook进程

    https://www.cnblogs.com/Leo_wl/p/3311279.html https://blog.csdn.net/u013761036/article/details/65465 ...

  2. FTP 搭建

    FTP 搭建 FTP 是 File Transfer Protocol(文件传输协议)的英文简称,它工作在 0SI 模型的第七层,TCP 模型的第四屋上,即应用层. 一.FTP 简介 FTP 会话时包 ...

  3. sublime3 多行编辑.摘抄

    Sublime text 3是一个非常强大的网站编辑工具. 这里小云深深的被它的快速编辑多行内容功能所吸引. 先说下,使用下面的功能要安装一个叫emmet的插件.没有的话,自行度娘吧. 下面就来看下具 ...

  4. Ckeditor上传图片返回的JS直接显示出来,未执行!!!

    Ckeditor上传图片网上有很多教程. 下面是我今天下午遇到的一个坑...自己挖的坑. 在conotroller里 我开始习惯性的 response.setContentType("app ...

  5. Jsp的语法和指令

    Jsp的三种注释 前端语言注释:<!-- --> 会被转译,也会被发送,但是不会被浏览器执行 java语言注释: 会被转译,但是不会被servlet执行 Jsp注释:<%--  -- ...

  6. 2018.10.16 NOIP模拟 膜法(组合数学)

    传送门 原题,原题,全TM原题. 不得不说天天考原题. 其实这题我上个月做过类似的啊,加上dzyodzyodzyo之前有讲过考试直接切了. 要求的其实就是∑i=lr(ii−l+k)\sum _{i=l ...

  7. 2018.08.19 洛谷P1402 酒店之王(最大流)

    传送门 最大流入门题,把人拆点即可. 代码: #include<bits/stdc++.h> #define N 505 using namespace std; inline int r ...

  8. 2018.07.08 NOIP模拟 好数(线段树)

    好数 题目背景 SOURCE:NOIP2016-AHSDFZ T3 题目描述 我们定义一个非负整数是"好数",当且仅当它符合以下条件之一: 1. 这个数是 0 或 1 . 2. 所 ...

  9. yii2 内置事件

    1.yii2系统登录   const EVENT_BEFORE_LOGIN = 'beforeLogin';  //登录前    const EVENT_AFTER_LOGIN = 'afterLog ...

  10. 关于linux下/srv、/var和/tmp的职责区分

    转载自:https://blog.csdn.net/u012107143/article/details/54972544?utm_source=itdadao&utm_medium=refe ...