前端:时间你用对了吗?
创始人
2024-01-25 05:18:02

导读: 前后端接口中的时间是怎么约定的?

项目中是否有遇到过时区问题引发的bug?

时间应该遵循什么样的使用规范?

如何理解并处理跨时区问题?

关键字:时间戳、时区、设备本地时间、北京时间

1. 支付宝中的跨时区问题

开门见山举例:

场景1:同笔账单时间不同?

如果我在日本(比北京时间快1小时)使用支付宝,将看到如下效果

  • 小荷包 -> 余额:从小荷包中转出一笔到余额, 小荷包中看到的是19:02,进到余额中看到的是18:02
  • 消息盒子->账单详情:消息盒子提醒我13:58发生一笔消费,点进去之后账单详情显示时间是12:58
  • 会员积分兑换:一笔兑换记录,Tab2 积分兑换显示的是 19:13,Tab1 收支明细显示为 18:13

为什么以上时间不同?

传输和显示时间的方式不同。有的是后端下发北京时间字符串值,如:"2022-11-14 18:02",有的是后端下发时间戳,由前端转化成最终的时间字符串dateFormat(timestamp, "YYYY-MM-DD hh:mm")

场景2:定时场景的时间歧义

如果我在旧金山(比北京时间慢16小时)使用支付宝,将看到如下效果

  • 预约转账-提前转:选择2022-12-31定时转账,结果提前了1天2022-12-30就进行了转账。
  • 预约转账-转账失败:选择2022-05-14 给某人转账,结果到了这天,提醒我转账失败了(服务器时间校验未通过)。

为什么会发生上面的情况?

  • 用户期望使用旧金山时间"2022-12-31"进行转账,但后端收到之后当做北京时间处理,于是在北京时间"2022-12-31"(对应旧金山时间 2022-12-30)进行了转账。
  • 用户传给服务端的时间transferDay 为14号(本机时间13号+ 1) ,服务端需要与另外一个字段nextTaskTime为15号(服务器时间14号+1) 进行对比校验,二者不一致则校验不通过。

灵魂拷问:下列跨时区服务场景中 哪些按北京时间执行?哪些按设备本地时间执行 ?

场景3:账单、凭证类服务

现状:账单、凭证类服务多数是使用的"北京时间"。

  • 问题: 大多数同学(前端、后端、产品、业务)不太了解跨时区概念,不知道什么场景使用"北京时间",什么场景使用"设备本地时间"。

问题总结

  1. 跨时区场景1个应用可能存在2套时间线,导致理解时间线混乱,多个应用间理解时间线更加混乱
  2. 定时场景容易出"Bug",用户不理解时区概念,容易发生系统执行时间和用户预期时间不一致的情况。
  3. 业务对跨时区问题感知比较弱,业务、技术同学不了解这个使用场景。

上文是支付宝中存在的一些跨时区问题,市面上其他知名APP是怎么处理跨时区问题的呢?

2. 其他APP跨时区问题调研

2.1 调研范围

...

 

2.2 调研分析

应用

调研范围

调研分析

微信

消息列表、会话详情、账单、零钱、朋友圈

所有页面全部使用设备本地时间

调研中唯一一个时间使用方式统一的APP

QQ

消息页面、QQ空间、收藏页面、交易记录页面

消息、QQ空间、收藏中的时间是设备本地时间

消息中的登录时间、交易记录的时间是北京时间

推演:前者的时间属性弱感知,后者时间属性强感知

抖音

会话页面、退款页面、退款页面、订单页面、足迹页面

会话消息、退款详情、退款的时间是设备本地时间

订单详情、订单评价、我的足迹的时间是北京时间

总结:订单时间使用北京时间能理解,但是更明显的趋势是抖音中对于时间使用是没有明显规范的。

淘宝

会话页面、问大家页面、订单页面、零钱页面、评论页面

消息会话、问大家中的时间是设备本地时间

订单详情、零钱账单、精选评论中的时间是北京时间

总结:消息、订单、账单的时间使用对比其他APP有明显相似的趋势,其他服务则没有明显的使用规范。

拼多多

交易页面、会话页面、浏览记录页面、多多视频评论页、大促评论

交易通知、会话消息、评论中的时间是设备本地时间

交易详情、浏览历史中的时间是北京时间

总结: 会话消息、评论、订单的时间使用依然是表现为相似的趋势,除此之外的服务没有明显的使用规范。

招商银行

账单页面、评论页面

使用北京时间

中国银行

账单页面、资产统计时间模块

使用北京时间

工商银行

账单页面、资产统计时间模块、明细页面

使用北京时间

支付宝

账单、资金业务、咨询、生活服务、常规基础功能服务业务

账单、资金相关业务大部分的时间是北京时间

其他基础功能服务、生活服务等普遍存在北京时间和设备本地时间滥用的情况

2.3 调研总结

  1. 账单类服务无论是 互联网公司 还是 传统银行 都更倾向使用北京时间
  2. 消息会话类服务 更倾向使用 设备本地时间
  3. 国内 互联网公司 中多数并不care跨时区问题
  4. 传统银行 对时间的使用有明显规则 => 使用北京时间

3. 跨时区问题分析

  • 什么场景需要关注跨时区问题?

    存在一定国际化用户的业务

  • 应该效仿微信、银行App全部服务使用 "设备本地时间" 或 "北京时间"?

    如果你的服务跟账单关系不大,全部用"设备本地时间"的体验会更好; 如果你是个类似银行类的账单服务,全部用"北京时间"吧能省心很多; 如果你是个类似支付宝的超级应用,那就二者都要有;

  • 时间字段使用的规则? 跨时区场景中什么时候使用"设备本地时间" or "北京时间"?

上文的调研分析得出:

1. 账单、订单、资金明细、凭证: 使用北京时间

2. 会话消息: 使用设备本地时间

  • 从用户角度而言,最佳的体验是不感知跨时区 ==> 应用中的时间信息跟随设备时区时间。
  • 账单类服务相对特殊,需要保持"一致性" 与 "不变性", 同一份账单在不同子应用、跨APP中需要保持一致。

🌰:你的转账记录,需要在转账记录、余额、账单、银行账单、电子单、凭证以上所有链路上保持一致。

其次是凭证、电子单、银行流水等部分服务具有一定的法律效力(可能会被当做证据使用)不适合随时区变化。

转账记录

余额

账单

银行账单

电子单

凭证

2022-11-01

一致:Good

2022-10-30

2022-10-30

2022-11-01

2022-11-01

2022-10-30

2022-11-01

不一致:Bad

最后得出规则:

1. 账单、订单、电子单、交易明细等 存在"账单"属性的服务使用北京时间

2. 第一点以外的所有服务,包括:消息、实时通知、评论等,都使用设备本地时间

  • 如何优化跨时区场景的用户体验?
  • 跨时区的核心问题:业务和用户都不了解跨时区场景,导致跨时区中时间线比较混乱。
  • 得出目标: 解决跨时区场景下时间线混乱的问题。
  • 优化思路:跨时区下使用 "北京时间" and 首次发生 "时区变更" 时(最容易引发“时间理解混乱”的时候) 进行时区信息提示(目的: 与用户对时间信息理解上的达成一致)。

通过分析总结出关于时间使用方面的 "正确姿势" 👇👇👇👇👇👇

4 时间的正确使用姿势

4.1 核心原则&使用规范

核心原则:保障时间理解的一致性与系统执行时间的准确性

  • 理解的一致性:用户心理预期的时间与产品预期传达的时间是一致的。
  • 执行的准确性:满足前者的情况下,做到系统真实执行的时间准确匹配产品预期的时间。

前者是产品角度,后者是技术角度。

使用规范:

  • "账单"类服务统一使用北京时间,"账单"类服务以外使用设备本地时间。
  • 跨时区下使用北京时间的服务需要进行提示,使用设备本地时间的服务在时区变化时需要进行提示。

4.2 时区提示

就不放了...

5. 组件&工具库

就不放了...

5.2 工具库(时间转换)

如果服务端一定要求前端传YYYY-MM-DD格式时间(不推荐,推荐传时间戳)的时候

前端不能直接通过dateFormat(timestamp, "YYYY-MM-DD") 格式化之后传值给服务端(这是本机时间的日期,需要传北京时间的日期),可使用这个方法进行转换,避免手动处理时区偏移量

import { getBjByLocalTime } from '就不放了';
/*** @param timeStr  国外本地时间(YYYY-MM-DD HH:mm:ss)| 时间戳* @returns dayjs obj*/
getBjByLocalTime('2022-10-03 12:00') // 日本东京时区
// 返回北京时间dayjs对象

如果服务端只下发了YYYY-MM-DD格式时间(不推荐,推荐下发时间戳)的时候,但业务需要展示本地时间

前端不能直接使用该YYYY-MM-DD格式时间,可使用这个方法把北京时间YYYY-MM-DD 转成 国外本地时间,避免手动处理时区偏移量

import { getLocalByBjTime } from '就不放了';
/*** 北京时间YYYY-MM-DD 转 国外本地时间* @param timeStr 北京时间, 支持YYYY-MM-DD HH:mm:ss | 时间戳* @returns dayjs obj*/
getLocalByBjTime('2022-10-03 12:00')
// 返回用户本地时区dayjs对象

当业务需要自定义提示用户本地时区,可通过以下方法拿到本地时区的中文信息,如:东京(日本)-东9区

import { getTzNameCn } from '就不放了';
import { getTzStr } from '就不放了';getTzNameCn() // 返回 纽约(美国)
getTzStr() // 返回 西5区 | 东6区 | 中时区

6. 服务端如何处理跨时区

时间设置,关注时区和时令,避免设置当地值,string传值带时区。

  • 时间设置要关注闰年、夏令时、时区。服务器时间都要设置成为UTC(海外)或者GMT+8(国内),一定不能设为当地时间(北美、欧洲、澳洲一些国家都有夏令时)。
  • 时间不要用datetime,要用timestamp。用string传时间,一定要ISO格式带上时区信息。

服务器在国外时,严禁使用服务器本地时间(冬夏令时会发生服务器时间跳变),推荐设置为UTC时间。

常见: 服务器在国内时,推荐使用服务器本地时间(GMT+8)。

国内服务器的情况下服务端尽量不感知时区概念, 一概理解成接收和使用的时间都是"北京时间"。

7. 测试回归

就不放了

End

相关内容

热门资讯

什么是419 419是什么意思... 嗨,辣条陪你理智吃瓜最近刚还想着10月特殊时期可能没啥瓜了,结果一到月底就来了。孟美岐冷不丁就突然上...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
什么是419 419是什么意思... 嗨,辣条陪你理智吃瓜最近刚还想着10月特殊时期可能没啥瓜了,结果一到月底就来了。孟美岐冷不丁就突然上...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...