toTimeString方法时区名称不一致问题及相关技术疑问
观察到的现象
不同构造方式的Date实例输出差异
const date1 = new Date("2022-09-23T00:00:00.00Z") const date2 = new Date() date1.toTimeString() // 输出:17:00:00 GMT-0700 (Pacific Daylight Saving Time) date2.toTimeString() // 输出:15:06:43 GMT-0800 (Pacific Standard Time)
设备区域设置对date1输出的影响
date1.toTimeString() // 设备区域设为加拿大时 // 输出:17:00:00 GMT-0700 (Pacific Daylight Saving Time) // 设备区域设为美国时 // 输出:17:00:00 GMT-0700 (Pacific Daylight Time)
date2输出不受区域设置影响
date2.toTimeString() // 美国和加拿大区域下结果一致 // 输出:15:06:43 GMT-0800 (Pacific Standard Time)
疑问解答
为何toTimeString结果依赖Date实例的构造方式?
两个实例对应的时间戳处于夏令时的不同时段:date1指向的2022年9月23日属于北美太平洋时区的夏令时周期(时区偏移为GMT-0700),而date2是当前时间(假设处于冬令时周期,偏移为GMT-0800)。toTimeString()会根据时间戳所在时段,返回对应时区的夏令时/标准时名称,因此不同构造方式(对应不同时间点)会产生结果差异。为何
new Date("2022-09-23T00:00:00.00Z")的toTimeString结果受设备设置影响?
北美不同国家对同一夏令时的时区名称表述有差异:美国太平洋夏令时称为Pacific Daylight Time,加拿大则称为Pacific Daylight Saving Time。toTimeString()会读取设备的区域设置,匹配对应区域的时区名称表述规则,因此不同区域设置下输出的名称会不同。无参构造的Date实例调用toTimeString的结果似乎不受区域影响,是否可认为其时区名称不受设备设置影响?
不是。当前时间处于冬令时周期,美国和加拿大太平洋时区的冬令时名称统一为Pacific Standard Time,因此这两个区域设置下输出一致。如果当前时间处于夏令时,或切换到其他存在名称差异的区域,结果仍会随区域设置变化。为何
new Date().toTimeString()不受区域设置影响,与问题2的情况相反?
原因和问题3一致:当前时间处于冬令时,美国和加拿大太平洋时区的冬令时名称表述统一,因此不同区域设置下输出相同。若当前时间处于夏令时时段,该方法的输出仍会随设备区域设置改变。
补充说明
该行为并非异常,而是toTimeString()的标准逻辑:对于实行夏令时的时区,方法会根据时间戳所处的具体时段(夏令时/冬令时)返回对应时区名称,同时时区名称的表述遵循设备的区域设置。另外,date-fns-tz也存在相同行为,因为其底层依赖原生Date的时区处理逻辑。
内容的提问来源于stack exchange,提问作者tpszhao

