如何使不同时区的时间与京8区一致?(JS实现)
如何使不同时区的时间与京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实现)的更多相关文章
- 关于时区的时间的详解,比如UTC\GMT等
UTC 和 GMT 及 北京时间的关系 UTC和GMT,这两者几乎是同一概念.它们都是指的格林尼治标准时间,只不过UTC的称呼更为正式一点.两者的区别在于前者是一个天文 上的概念,而 后者是基于一个原 ...
- openerp 常见问题 OpenERP为什么选择了时区后时间还是不对?(转载)
OpenERP为什么选择了时区后时间还是不对? 原文地址:http://cn.openerp.cn/%E4%B8%BA%E4%BB%80%E4%B9%88%E9%80%89%E6%8B%A9%E4%B ...
- Linux系统的时区和时间调整
linux调整系统时区: 1)tzselect命令 找到相应的时区文件/usr/share/zoneinfo/Asia/Shanghai,用这个文件替换当前的/etc/localtime文件. 或者 ...
- 查看修改Linux时区和时间
查看/修改Linux时区和时间 一.时区 1. 查看当前时区 date -R 2. 修改设置时区 方法(1) tzselect 方法(2) 仅限于RedHat Linux 和 CentOS timec ...
- javascript通过时区获取时间
/* 描述:时区的换算 参数:offset时区位置 使用:东八区calcTime(”+8"); */ function calcTime(offset) { // 创建一个本地日期 var ...
- NSDate获取当前时区的时间
[NSDate date]获取的是GMT时间,要想获得某个时区的时间,以下代码可以解决这个问题 NSDate *date = [NSDate date]; NSTimeZone *zone = [NS ...
- centos修改时区,设置时间
在我们使用CentOS系统的时候,也许时区经常会出现问题,有时候改完之后还是会出错,下面我们就来学习一种方法来改变这个状况.如果没有安装,而你使用的是 CentOS系统 那使用命令 yum insta ...
- LINUX更改时区和时间
因为公司运营海外游戏,服务器也多数放在国外,有时候要求服务器时区和时间要与所服务的地区一致,这里就涉及到更改服务器时区和时间的问题: 下面以一台在美国的服务器为例,我们的IDC提供商是一家德国公司,服 ...
- Java 时区之间时间转换
SimpleDateFormat foo = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); System.out.println(&qu ...
随机推荐
- connect strings sql server
https://www.connectionstrings.com/sql-server/ Server=myServerAddress[,port];Database=myDataBase;User ...
- SQL0973N在 "<堆名>" 堆中没有足够的存储器可用来处理语句
SQL0973N在 "<堆名>" 堆中没有足够的存储器可用来处理语句. 解释: 已使用此堆的所有可用内存.不能处理该语句. 用户响应: 接收到此消息(SQLCODE)后 ...
- 2018.09.27 codeforces618F. Double Knapsack(抽屉原理+构造)
传送门 思维题. 考虑维护两个数列的前缀和a1,a2,a3,...,ana_1,a_2,a_3,...,a_na1,a2,a3,...,an和b1,b2,b3,...,bnb_1,b_2,b_ ...
- 2018.07.08 NOIP模拟 ABCD(背包)
ABCD 题目背景 SOURCE:NOIP2016-AHSDFZ T2 题目描述 有 4 个长度为 N 的数组 a,b,c,d .现在需要你选择 N 个数构成数组e ,数组e 满足 a[i]≤e[i] ...
- 浅谈OCR之Tesseract
光 学字符识别(OCR,Optical Character Recognition)是指对文本资料进行扫描,然后对图像文件进行分析处理,获取文字及版面信息的过程.OCR技术非常专业,一般多是印刷.打印 ...
- BZOJ 1003 物流运输 (dp + dijkstra)
1003: [ZJOI2006]物流运输 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 8672 Solved: 3678[Submit][Stat ...
- (线段树)Mayor's posters --poj -- 2528
链接: http://poj.org/problem?id=2528 覆盖问题, 要从后往前找, 如果已经被覆盖就不能再覆盖了,否则就可以覆盖 递归呀递归什么时候我才能吃透你 代码: #include ...
- (线段树 && 字符串的处理)codeforces -- 570C
链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87813#problem/J Description Daniel has a s ...
- HDU1258 Sum It Up(DFS) 2016-07-24 14:32 57人阅读 评论(0) 收藏
Sum It Up Problem Description Given a specified total t and a list of n integers, find all distinct ...
- android插件化简述
2015年是Android插件化技术突飞猛进的一年,随着业务的发展各大厂商都碰到了Android Native平台的瓶颈: 从技术上讲,业务逻辑的复杂导致代码量急剧膨胀,各大厂商陆续出到65535方法 ...