为何Intl.supportedValuesOf('timeZone')无最新时区信息?求替代方案
为什么
Intl.supportedValuesOf('timeZone')返回过时时区? Intl.supportedValuesOf('timeZone')的时区数据完全依赖JS引擎内置的ICU(Unicode国际化组件)库,而ICU的时区数据同步自IANA时区数据库,但浏览器/Node.js的引擎更新节奏和IANA的时区更新不同步:
- IANA通常每1-2个月就会发布时区数据更新(比如修正时区规则、废弃旧ID、新增时区),但JS引擎只会在大版本迭代时才会同步最新的ICU数据,小版本更新一般不会碰这部分。
- 为了兼容性,引擎不会轻易移除已废弃的时区ID,即使IANA已经标记它们过时,比如
Asia/Saigon这类只是更名的ID,依然会被保留在列表里,避免旧代码报错。
获取有效时区列表的替代方法
1. 用第三方日期库获取最新时区
像luxon、dayjs(配合dayjs-plugin-timezone)这类现代日期库,会主动维护最新的IANA时区数据,不依赖引擎的ICU:
- luxon示例:
import { Zone } from 'luxon'; const validTimeZones = Zone.names(); // 返回过滤掉废弃ID的最新时区列表
- dayjs示例:
import dayjs from 'dayjs'; import timezone from 'dayjs/plugin/timezone'; import utc from 'dayjs/plugin/utc'; dayjs.extend(utc); dayjs.extend(timezone); const validTimeZones = dayjs.tz.names();
2. 直接基于IANA时区数据库维护列表
你可以直接从IANA官方的tzdata包中提取最新的时区ID列表,或者使用专门的npm包(如iana-tz-data)来获取数据源,这种方式需要定期更新依赖以同步IANA的最新变更,适合对数据准确性要求极高的场景。
3. 手动过滤废弃时区
如果不想引入第三方库,可以结合IANA的废弃时区清单,对Intl.supportedValuesOf('timeZone')的结果进行过滤。比如维护一个废弃ID的黑名单,遍历列表时剔除这些项:
const deprecatedTimeZones = new Set(['Asia/Saigon', 'Pacific/Ponape', /* 其他废弃ID */]); const allTimeZones = Intl.supportedValuesOf('timeZone'); const validTimeZones = allTimeZones.filter(tz => !deprecatedTimeZones.has(tz));
不过这种方式需要你自己跟进IANA的时区变更,定期更新黑名单,比较繁琐。
内容的提问来源于stack exchange,提问作者muki
相关产品推荐
相关产品推荐

