如何在JavaScript中解析Wikidata中包含公元前的ISO格式日期
可行解决方案如下
方案1:使用专业日期库(推荐)
直接使用js-joda生态的工具包,该库完全脱离原生Date对象实现日期逻辑,不受原生日期的范围限制,原生全量支持ISO 8601格式解析,包含带负号的公元前日期,同时支持时区转换,完全覆盖Wikidata的日期返回格式。
你需要安装三个包:@js-joda/core核心库、@js-joda/timezone时区支持包、@js-joda/extra扩展功能包(可选)。
示例使用代码:
import { ZonedDateTime, ZoneId } from '@js-joda/core'; import '@js-joda/timezone'; // 解析示例公元前日期 const wikidataIsoDate = '-0709-01-01T00:00:00Z'; const utcDate = ZonedDateTime.parse(wikidataIsoDate); // 转换为目标时区,例如东八区 Asia/Shanghai const targetZonedDate = utcDate.withZoneSameInstant(ZoneId.of('Asia/Shanghai')); // 直接获取对应时区下的日期时间值 const year = targetZonedDate.year(); // 公元前年份返回负值,本例返回-709 const month = targetZonedDate.monthValue(); // 1-12对应1月到12月 const day = targetZonedDate.dayOfMonth(); const hour = targetZonedDate.hour(); const minute = targetZonedDate.minute();
该方案不需要自己处理正则匹配,库本身已经覆盖了所有标准ISO 8601的变体格式,包括不同精度的日期(仅年份、仅年月等格式)。
方案2:自定义解析逻辑(无依赖场景)
如果不希望引入第三方依赖,可以通过分层解析逻辑实现,比单条正则的兼容性更高:
- 第一步:按
T字符分割输入字符串,前半部分为日期段,后半部分为带时区的时间段 - 第二步:处理日期段,按
-分割:如果第一个元素为空字符串,说明是公元前日期,取第二个元素转为负值作为年份,后续元素依次为月、日;如果第一个元素为非空数字,直接作为公元年份 - 第三步:处理时间段,先去除末尾的
Z标识或时区偏移部分,按:分割依次得到时、分、秒 - 第四步:时区转换可手动计算偏移量,不需要调用原生
Date的解析逻辑
注意:ISO 8601标准中用0年表示公元前1年,部分场景下需要做年份对齐调整,Wikidata返回的日期已经适配该规则,可以直接使用。
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

