var d = new Date();
// returns correct value "Fri Sep 26 2014 01:16:31 GMT+0300 (E. Europe Daylight Time)"
d.toString();
// returns incorrect value one hour behind "9/26/2014 12:16:31 AM"
d.toLocaleString();
似乎toLocaleString()没有将DST考虑在这个测试用例中。
如何按日期计算当地时间(例如,Chrome是否自行应用DST规则或通过操作系统)以及算法在toString()和toLocaleString()之间的差异如何/为何?
这是一个错误还是预期的行为?
在Chrome / 37.0.2062.120上测试,位置塞浦路斯尼科西亚(http://www.timeanddate.com/time/zone/cyprus/nicosia)
答案 0 :(得分:4)
在预感中,我尝试将我的Windows时区更改为:
TZ Key / ID: "E. Europe Standard Time"
Display name: "(UTC+02:00) E. Europe"
重新启动Chrome后,我就可以获得您展示的相同内容:
仔细研究一下本地化属性:
因此,似乎Chrome无法理解时区。这是因为Chrome使用了ICU,它使用CLDR mappings用于Windows时区。该特定时区现在被视为“无法映射” - 因为没有与此Windows区域匹配的IANA时区标识符。
请注意,此区域已使用映射到Asia/Nicosia
,但在CLDR的最新版本中已更改,如CLDR #6973
出现差异的原因是toLocaleString
函数使用ECMAScript Internationalization API,而toString
则不然。先验取决于ICU和CLDR,而后者只是要求操作系统提供时区字符串。
修复方法是让用户将时区切换到正确的设置。塞浦路斯应该是:
TZ Key / ID: "GTB Standard Time"
Display name: "(UTC+02:00) Athens, Bucharest"
查看Windows时区控制面板中的选项时:
确保在更改时区后完全关闭所有Chrome窗口,因为Chrome在重新启动之前无法正确初始化时区。
现在,评论中的issue I mentioned earlier仍然存在问题,因为Intl.DateTimeFormat().resolvedOptions().timeZone
现在返回Europe/Kiev
,它应该返回Asia/Nicosia
或Europe/Bucharest
。但至少在大多数情况下,返回toLocaleString
的正确值是足够好的。