技术博客
同一个页面的时间变来变去,啥原理
admin2022-10-21 05:30
483人已围观
简介同一个页面的时间变来变去,啥原理
本文来自微信公众号:低并发编程 (ID:dibingfa),作者:闪客
事情的起因是这样的,之前我发了 Spring 的一个官方技术大会 SpringOne 的预告。
其中里面的大会时间表在官网是这样的。
大家注意看大会第一项的时间栏里,写的是:
9:00 PM - 10:00 PM CST
也就是当天晚上的九点正式开始(八点开始有影像)。
但有个读者这样一条评论引发了我的思考。
我查了下 CST 这个时区缩写,分别可以表示以下这么多时区的缩写:
美国中部时间:Central Standard Time (USA) UTC-6:00
澳大利亚中部时间:Central Standard Time (Australia) UTC+9:30
中国标准时间:China Standard Time UTC+8:00
古巴标准时间:Cuba Standard Time UTC-4:00
我是通过分析得出,如果是美国时间的晚上 8 点开始,那整个会就大部分都是凌晨多进行的,感觉不大合理,所以推测这应该是中国的时间,也就是 China Standard Time UT+8:00。
但细想想又觉得不大对劲,这 Spring 官网还照顾到我是中国人,然后专门为我显示中国时间?而且它是咋知道我是中国人的呢?
我让我一个美国的朋友访问了下这个页面,果然时间和我显示的不一样:
是 6:00 AM - 7:00 AM PDT
PDT 代表太平洋夏令时 Pacific Daylight Time UTC-7:00
我又让我一个英国的朋友访问了下,得到:
2:00 PM - 3:00 PM BST
BST 代表英国夏令时间 British Summer Time UTC+1:00
我又让我一个德国的朋友访问了下,得到:
3:00 PM - 4:00 PM CEST
CEST 代表欧洲中部夏令时间 Central Europen Summer Time UTC+2:00
我国外就这么些朋友了,这事就得到了验证,SpringOne 官网上我看到的 CST 肯定就代表中国时间了,因为这个网站显示的时间会随着访问人的时区而变化。
啥原理
然后我又想,这原理应该是请求头加了什么参数,标识了我的时区?
可是我抓包后,没发现有类似的参数。
然后我又想,那应该是根据我的请求 IP 判断的?
于是我 [那啥] 了一下,发现无论怎么切换 vpn,显示的时间一直是 CST,中国时间。
正当一筹莫展的时候,我又问了我一个快回国的英国朋友,他访问之后居然显示的也是中国时间!
9:00 PM - 10:00 PM CST
然后他说了一句话,一句点醒梦中人,他说他马上就要回国了,为了提前适应,所以把电脑的时区设置成了中国。
原来如此!
我马上把我的时区调整成了美国的太平洋时间。
重新打开浏览器,访问 SpringOne。
时间终于变成了美国太平洋时间,证明了美国人是早上开始看这个大会,然后持续一整天。我们中国人是晚上开始看,然后如果要追直播则需要通宵了。
同时也证明了,页面上显示的时间,和我操作系统系统设置的时区有关。
刨根问底继续探索
话说回来,这个网站的 H5 页面,是怎么和我系统的时间打交道的呢?
我开始抓包。
首先这个肯定不是个静态页面了,因此一定是个 js 动作。
在茫茫一片 js 包中我找到了一个叫 schedule.js 的,一看就是负责给这些时间赋值的。
注意到这里面在获取时间时,大量用了 getUnixTimestamp 方法。
于是我又在另一个 js 里面找到了这个方法的定义,在 core.min.js 里。
这个方法被压缩了,把它格式化一下,再拎出关键信息,如下:
$tzDatetimes:$(".tz-datetime") a.$tzDatetimes.each(function() { d.convertDatetime(this) }) convertDatetime:function(b) { var c=b.dataset.datetimeOut } var h = moment.tz.guess() var c = b.dataset.datetimeOut getUnixTimestamp:function(b,c){ return moment .tz(b,c"MM/DD/YYYY HH:mm", "America/New_York") .tz(h) .valueOf() }
重点看这个函数
var h = moment.tz.guess()
这个函数就是和系统设置时区交互的关键,它可以查看你的所在时区,准确说是你系统设置的时区。
我把系统时区设置成美国太平洋时区(UTC-8:00),浏览器 console 里执行这个 js 代码后,得到如下结果:
moment.tz.guess(); "America/Los_Angeles"
我又把系统时区设置成中国北京时间(UTC+8:00),浏览器 console 里执行这个 js 代码后,得到如下结果:
>> moment.tz.guess(); "Asia/Shanghai"
这一切就通了,这个 js 函数可以获取到我们系统设置的时区,也就自然可以随着系统时区,来动态变化页面上的时间了。
具体怎么变化,就是通过刚刚的 getUnixTimestamp 这个函数了。
getUnixTimestamp:function(b,c){ return moment .tz(b,c"MM/DD/YYYY HH:mm", "America/New_York") .tz(h) .valueOf() }
我们知道 h 就代表时区,那么这第一行 tz 就是用美国纽约时间来设定一个初始值,第二行 tz 转化为我们系统设置的时区,第三行 valueOf 最终可以转化成一个时间戳。
我们随便拿一个值浏览器 console 里执行这个函数验证一下,比如我们想看看美国纽约时间的 2021-09-01 08:00 转换成北京时间(我系统设置的时间)的结果是什么。
moment \ > .tz("09/01/2021 08:00","MM/DD/YYYY HH:mm", "America/New_York") \ > .tz(moment.tz.guess()) \ > .valueOf() 1630497600000
这个 1630497600000 用时间戳转换工具转换下,就是:
完美,这个函数把美国纽约时间的 2021-09-01 08:00 转换成了北京时间的 2021-09-01 20:00,刚好差 12 个小时嘛,没毛病。
于是乎这个转换后的值,就填充到页面上 class 为 tz-datetime 这个标签下了。
$tzDatetimes:$(".tz-datetime") a.$tzDatetimes.each(function() { d.convertDatetime(this) })
没错,就是我们看到的位置。
至此,本问题终于完美解释了!
感谢这位读者提出的问题,感谢各国亲朋好友提供的支持,让我有了一个快乐探索的下午,以及这篇随性而发的文章!
做技术人我觉得这点比较好,就是毫无目的,只为解答一个心中的疑惑,就愿意花上一下午时间去研究研究,同时得出结论后的那种快乐,我觉得是独有的一种享受。
那我的话还有双倍快乐,就是写成文章给大家看,看大家的留言、点赞。
希望对大家有帮助~

微信公众号
很赞哦!(0)
相关文章
文章评论
评论0
站点信息
- 微信公众号:扫描二维码,关注我们

点击排行

标签云
-
php
网页设计
个人博客
JS
个人博客
Html
春节必看: 2020新春红包大战 全攻略
新增详细玩法攻略!
支付宝集五福5亿集分宝招商银行抽现金券抖
抖音 2020 发财中国年 攻略
支付宝集五福5亿集分宝招商银行抽现金券抖
最近购买威尔胜WTB0900复刻版和WT
mysql慢查询和php-fpm慢日志
PSR-2
基础代码规范
Thinkphp
响应式
公司
整站
源码
网络科技网站模板
1024
节日
百度收录
论坛
社区
2020
豆瓣
评分最高
电影
debugger
调试
Python
语法
高德
百度地图
MySQL
追寻
webpack
vue
oracle
服务器搭建
有趣
动物
人体
历史
天文
生活
名人
体育
地理
文化
科学
心理
植物
饮食
自然
图片
JVM
IDEA
Loader
Git
UNIAPP
股票
A股
同花顺
海尔
海天味业
半年报
股市总结
歌尔股份
乐普医疗
涪陵榨菜
餐饮
财报分析
酒店
年报分析
美锦能源
山煤国际
贵州茅台
张坤
腾讯
华鲁恒升
淮北矿业
药明康德
早盘关注
国电电力
北方华创
宝丰能源
TCL中环
兔宝宝
天润乳业
启明星辰
阳光电源
山西汾酒
迈瑞医疗
人福医药
比亚迪
宁德时代
汤臣倍健
伊利股份
通威股份
东鹏饮料
隆基股份
紫金矿业
五粮液
康龙化成
赣锋锂业
爱尔眼科
片仔癀
VR
永新股份
爱美客
美的集团
格力电器
科沃斯
云南白药
同仁堂
洋河股份
白云山
三体
狂飙 原著