保留毫秒精度将UTC时间/日期转换为本地时间/日期的实现方法咨询
ISO 8601带Z标记的UTC时间转本地时间(保留毫秒精度)方法
你拿到的2021-01-14T17:00:23.87Z 是符合ISO 8601标准的UTC时间字符串,末尾的Z代表这个时间是零时区的标准时间,没有附带本地时区偏移。
通用计算步骤
整个流程可以全程保留毫秒精度,因为所有时区偏移都是整分钟/整小时级别的,不会对毫秒位造成干扰:
- 第一步:拆解输入字符串的所有时间分量,单独保留毫秒值
把字符串里的时间值拆成独立的数值:年、月、日、小时、分钟、秒、毫秒。其中字符串里小数点后的部分是秒的小数段,乘以1000就得到对应的毫秒值,比如示例里的.87,换算后就是870毫秒,直接单独存放,全程不要修改这个值。 - 第二步:确定目标本地时区在该时间点的实际偏移量
先查你要转换到的本地时区,对应该时间点和UTC的时差:- 没有夏令时、时区政策固定的地区,偏移量是固定值,比如东八区永远是+8小时
- 有夏令时调整、或者历史上调整过时区政策的地区,要取目标时间戳对应时刻的实际偏移,不能用当前时间的偏移硬套(比如中国1986-1991年实行过夏令时,计算那段时间的本地时间就要算上当时的1小时偏移)
- 第三步:叠加偏移量做进位计算
按照从最小时间单位到最大时间单位的顺序计算,避免日期错位:- 毫秒、秒、分钟三个小单位因为偏移量不会覆盖到这个精度层,直接用拆解出来的原值即可,完全保留精度
- 把偏移量折算成小时、分钟的总数值,叠加到UTC时间的小时、分钟计数上
- 叠加后如果小时数超过24,就按整天进位调整日期;如果小时数是负数,就借前一天的24小时换算日期,再对应调整月份、年份的天数(注意大小月、闰年2月的天数校验)
实际计算示例
就用你给的输入值计算:
输入UTC时间:
2021-01-14T17:00:23.87Z
假设转换为东八区本地时间(2021年1月没有夏令时调整,偏移量为+8小时)
- 拆解分量:年=2021,月=1,日=14,小时=17,分钟=0,秒=23,毫秒=870
- 叠加偏移:17小时 +8小时 =25小时
- 进位调整:25小时 = 1整天 +1小时,日期从1月14日进为1月15日,剩余小时数为1
- 最终得到的本地时间为:
2021-01-15 01:00:23.870,毫秒值全程没有改动,精度完全保留
避坑提醒
- 不要提前把时间截断到秒级再做转换,那样会直接丢掉毫秒部分的精度
- 计算时区偏移的时候不要张冠李戴,比如不要用冬令时的偏移去算夏令时的时间点
- 拆解字符串的时候不要直接把小数部分四舍五入成整秒再计算,要单独把小数段拆出来换算成毫秒值
内容的提问来源于stack exchange,提问作者Michele Soldani
相关产品推荐
相关产品推荐

