使用mdp-date-picker处理1967/09/24时区转换的异常问题
问题描述
1967年9月24日是欧洲/意大利时区从UTC+1切换至UTC+2的日期,使用AngularJS Material的mdp-date-picker组件时出现异常:
- 从后端获取时间戳
-71715600000,组件正确显示为24/09/1967; - 前端无任何修改直接保存后,模型中的时间戳变为
-71719200000; - 测试发现:同是Chrome浏览器,Windows系统下会使用UTC+2时区,而同时区配置的Linux系统下则使用UTC+1时区。
存在三个疑问:
- 仅通过时间戳
-71715600000和-71719200000,为何能识别出UTC+1和UTC+2时区? - 同时区配置下,Windows和Linux的Chrome处理为何不同?
- Windows Chrome保存的时间戳在后端存储过程的税号校验中报错(需UTC+1时区),Linux保存则正常。
解答
1. 从时间戳识别时区的原理
时间戳是UTC纪元(1970-01-01T00:00:00Z)起算的毫秒数,通过时间戳反推UTC时间,再结合本地日期就能算出时区偏移:
- 时间戳
-71715600000对应的UTC时间是1967-09-24T01:00:00Z,若本地日期显示为24/09/1967,说明本地时间=UTC时间+1小时,即时区为UTC+1; - 时间戳
-71719200000对应的UTC时间是1967-09-23T23:00:00Z,若本地日期仍为24/09/1967,说明本地时间=UTC时间+2小时,即时区为UTC+2。
本质是同一个本地日期对应了两个不同的UTC时间,两者的差值直接反映了时区偏移量。
2. Windows与Linux Chrome的处理差异
核心原因是两者依赖的时区数据源不同:
- Windows系统使用微软自研的时区数据库,对于1967年意大利这次历史时区变更,其记录的切换时间点可能与Linux不一致;
- Linux系统使用IANA(互联网编号分配机构)维护的标准时区数据库,对历史时区变更的时间点记录更精准。
Chrome解析本地日期为UTC时间戳时,会调用系统提供的时区接口,因此不同系统的时区数据差异,导致同一个本地日期24/09/1967被转换为不同的UTC时间戳。
3. 后端校验报错的原因
后端税号校验要求日期必须对应UTC+1时区的时间戳:
- Linux Chrome保存的
-71715600000,转换为UTC+1时区的本地时间是1967-09-24T02:00:00+01:00,日期仍为24日,符合校验规则; - Windows Chrome保存的
-71719200000,转换为UTC+1时区的本地时间是1967-09-23T23:00:00+01:00,日期变成了23日,不符合校验要求,因此报错。
内容的提问来源于stack exchange,提问作者fini Luca
相关产品推荐
相关产品推荐

