星辰大海▼ 2020▼ Tip 架构 Timezone I18n

技巧010:别把时区和多国语想简单了

#Tip #架构 #Timezone #I18n

凡是涉及到跨国业务的,一定会考虑多时区,偶尔也有考虑多语言。市面上多数号称支持多语言多时区的产品,要么有设计缺陷,考虑不足,要么功能难用,数据混乱。所以搞一篇基础知识科普,以便大家知晓地球是圆的而且会转。

1.问题:支持多语言多时区么?

甲方:“你们支持多语言,多时区和多货币么?”;乙方:“支持啊,我们”

  • 提供了不同的语言包,页面会自动切换。
  • 服务器远行在零时区上,中国用GMT+8,美国那边UTC-5

甲方:“服务器内部消息呢?比如业务警告,错误,异常”;乙方:“…”

甲方:“那美国有涉及夏令时么?”;乙方:“…”

注意,语言包,GMT, UTC,夏令时,这些词都大有故事,自行八卦。在《R036.时间,时区,闰秒》中也有提时间敏感系统的知识点,自行摸瓜。

2.语言,不仅仅是套语言包

多语言,是个系统工程,远不止一套语言包。每个提示语,每个错误信息,都要定义code。并且要考虑不同文字的长度对界面排版的影响。

  • 入门,页面元素对应语言包,语言按code取(UI)
  • 标配,业务逻辑端有enum,按enum输出文字或code(架构)
  • 旗舰,一类语言独立一套界面(UE)

所以,简单来说,多语言要做好,从code上着手,从架构上支持,从体验上提高。

3.时区,从场景和视角上考量

以跨境海淘场景为例,服务器群采用UTC时区(系统时间),中国用户Asia/Shanghai(用户时间), 纽约NY商家America/New_York(数据时间),洛杉矶LA商家America/Los_Angeles(数据时间)。 为什么说UTC-5初级呢?因为同一经线上国家很多,又要考虑夏令时,所以需要city标志zoneid

本地日时,必须有时区配合,又分为用户时间数据时间,命名后缀如下,

  • 时区 - 以_tz_zid为后缀,内容为ZoneId的字符串名字。
  • 日时 -系统/用户/数据,分别以_dt/_udt/_ldt结尾。
  • 日期 -系统/用户/数据,分别以_dd/_udd/_ldd结尾。
  • 时间 - 系统/用户/数据,分别以_tm/_utm/_ltm结尾。

举例,北京时间2020-08-09 01:00:00,中国用户C1,分表在NY和LA商家下单。

  • Sys_dt(UTC) = 2020-08-08 17:00:00
  • C1_udt(Asia/Shanghai, UTC+8) = 2020-08-09 01:00:00
  • NY_ldt(America/New_York, UTC-4) = 2020-08-08 13:00:00
  • LA_ldt(America/Los_Angeles, UTC-7) = 2020-08-08 10:00:00

哎,不对啊,记得纽约是西五区啊,应该UTC-5啊。是西五区,可现在是夏令时,就写UTC-4

系统时区,推荐为核心用户所在时区,因此,要考虑UTC是否为最优解。

于是,以下场景时,我们会用到不同的时间,

  • 当跟踪系统日志时,我们使用Sys_dt,可以保证统一的时间线。
  • 当统计北美商家上午的营运报表时,我们使用*_ldt
  • 当追求用户体验,用户不关心时区时,用户看到的所有时间都是C1_udt
  • 有些行业惯例(航空,物流)使用本地时间,我们使用*_ldt

按数据的读写比例,处理时间存储时,要考虑。

  • 统计类业务,通常写入时转化,存入用户本地时间(和时区),读取时不转换。
  • 协作类业务,通常写入时,使用系统时间,读取时转换。

※ 我们的征途是星辰大海 ※

《技巧010:别把时区和多国语想简单了》 凡是涉及到跨国业务的,一定会考虑多时区,偶尔也有考虑多语言。市面上多数号称支持多语言多时区的产品,要么有设计缺陷,要么数据混乱。所以搞一篇基础知识科普,以便大家知晓地球是圆的而且会转。
题图:Normally faint and elusive, the Jellyfish Nebula is caught in this alluring, false-color, telescopic view.