时区
我们的世界有数百个时区。 在JavaScript中,我们只关心两个, 本地时间和协调世界时(UTC)。
- 本地时间是指你的计算机所在的时区(比如中国是东八区, 即在 UTC 时间基础上加8小时)。
- UTC指协调世界时。协调世界时,又称世界统一时间、世界标准时间、国际协调时间。
默认情况下,JS中的几乎每个日期方法(除了一个)都是本地时间。 只有指定UTC,才能获得 UTC 时间 。
跨时区存储时间
因为各地的时间 都是 根据时间戳 与 时区 计算之后转换成当地时间, 所以如果要 世界各地都看到记录的时间都是一样的, 不会根据当地时区而改变 就要 记录时间存储地的时区。
比如:
在中国记录当前时间, 那么存储 当前时间戳 与 +8 的时区就行了
跨时区展示时间
在世界各地使用 new Date() 的部分 api 来获取时间都会自动的根据当地时区换算出当地的时间, 所有当项目有跨区需求的时候, 时间的展示就格外的重要了。
根据上面的 跨时区存储时间 方式, 下面提供 根据 时间戳 和 时区转换出 存储地的存储时间 的例子
这里为了 方便调试 和 理解, 将 demo 改为 input 输入框形式, 如果要结合上面的 跨时区存储时间, 可以将 存储的 时间戳 和 时区 的计算结果 传入 getUTCTime 方法中即可返回对应地区的对应时间
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form name="myform" id="my_form">
<p>被转换时间: <input type="text" name="timestamp" /></p>
<p>时区: <input type="number" name="timeZone" /></p>
</form>
<input type="button" onclick="submit()" value="提交" />
<input type="button" onclick="getNowTime()" value="录入当前时间" />
<div id="current_time">
转换之后的时间:
</div>
</body>
<script>
/**
* @author: yx
* @method: 获取当前的时间 和 当地时区 并 赋值给输入框
* @Date: 2021-06-08 11:20:56
*/
function getNowTime() {
const myform = document.getElementById('my_form');
const timeZone = document.getElementById('my_form');
// 拿到当前地区的 时区
myform.timeZone.value = -new Date().getTimezoneOffset() / 60;
// 根据 当前地区 获取 当前地区当前时间戳
const timestamp = new Date().getTime() + (myform.timeZone.value * 3600000);
// 将 当前地区当前时间戳 转换为 当前地区当前时间
myform.timestamp.value = getUTCTime(new Date(timestamp), 'yyyy-MM-dd hh:mm:ss');
}
/**
* @author: yx
* @method: 根据输入的 当地时间 和 需要转换的时区 获取 对应时区的时间
* @Date: 2021-06-08 11:19:53
*/
function submit() {
const myform = document.getElementById('my_form');
const currentTime = document.getElementById('current_time');
// 将 输入框中时间 转换为 时间戳 并 加上 输入框中时差
const timestamp = new Date(myform.timestamp.value).getTime() + (+myform.timeZone.value * 3600000);
// 将计算的最终时间戳 转换为 对应时区的时间
const date = getUTCTime(new Date(timestamp), 'yyyy-MM-dd hh:mm:ss');
currentTime.innerHTML = 'Current Time: ' + date;
}
/**
* @author: yx
* @method: 根据指定格式 返回 设置时区 对应的 时间
* @param {*} date: 加上时区之后的时间
* @param {*} fmt:需要返回的格式
* @Date: 2021-06-08 11:14:47
* 例子:
* formatTime(new Date(), "yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
* formatTime(new Date(), "yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
*/
function getUTCTime(date, fmt) {
let o = {
'M+': date.getUTCMonth() + 1, // 月份
'd+': date.getUTCDate(), // 日
'h+': date.getUTCHours(), // 小时
'm+': date.getUTCMinutes(), // 分
's+': date.getUTCSeconds(), // 秒
'q+': Math.floor((date.getUTCMonth() + 3) / 3), // 季度
S: date.getUTCMilliseconds() // 毫秒
};
// 替换指定 年 格式
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(
RegExp.$1,
(date.getUTCFullYear() + '').substr(4 - RegExp.$1.length)
);
}
// 通过循环替换 指定时间格式
for (let k in o) {
if (new RegExp('(' + k + ')').test(fmt)) {
fmt = fmt.replace(
RegExp.$1,
RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length) // 如果两位补0
);
}
}
return fmt;
}
</script>
</html>