如何显示公元前/公元或其他纪元标识?
使用 Intl.DateTimeFormat 的 era 选项显示公元、公元前及其他历法系统的纪元名称
简介
大多数情况下,您处理的日期都属于公历的当前纪元,因此通常无需显示纪元标识。例如,“2024年10月15日”即使不加“公元”也很清楚。但对于两千多年前的历史日期,纪元标识有助于明确年份是在公元前还是公元后。
不同文化也有各自的历法系统和纪元。例如,日本历法以天皇在位划分纪元,如令和、平成。佛历以佛陀涅槃为起点计年。伊斯兰历则以希吉拉(迁徙)为纪元起点。
JavaScript 的 Intl.DateTimeFormat 提供了 era 选项,可用于显示这些纪元标识。该选项不仅适用于公历,也支持其他历法系统,并会根据本地化习惯自动格式化纪元显示。
理解历法系统中的纪元
纪元是指从某一重大事件或起点开始计时的一段时期。公历有两个纪元:公元(AD,拉丁语“主的年份”)表示公元1年之后的日期,公元前(BC)表示公元1年之前的日期。
在显示历史日期时,纪元标识尤为重要。例如,公元500年和公元前500年相差一千年,仅用“500年”会造成歧义,添加纪元标识可以消除这种混淆。
其他历法系统对纪元的定义各不相同。日本历法每逢新天皇即位便更换纪元。佛历自公元前543年起采用单一纪元。每种历法系统都有自己的纪元显示规范。
在公历日期中显示纪元指示符
era 选项接受三个值,用于控制纪元的显示方式。值 long 显示完整的纪元名称。值 short 显示缩写形式。值 narrow 显示最简洁的表示方式。
const date = new Date('2024-10-15');
const long = new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
era: 'long'
});
console.log(long.format(date)); // "October 15, 2024 Anno Domini"
const short = new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
era: 'short'
});
console.log(short.format(date)); // "October 15, 2024 AD"
const narrow = new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
era: 'narrow'
});
console.log(narrow.format(date)); // "October 15, 2024 A"
long 值会在公元日期下显示 "Anno Domini"。short 值会显示 "AD"。narrow 值只显示 "A"。
对于现代日期,纪元指示符通常是多余的,因为默认假定为当前纪元。通常只有在显示历史日期且区分纪元很重要时才会包含纪元信息。
使用纪元指示符格式化公元前日期
JavaScript 通过负数年份或向 Date 构造函数传递负值来表示公元前日期。年份 -500 表示公元前 501 年,年份 -1 表示公元前 2 年,年份 0 表示公元前 1 年。
const bcDate = new Date(-500, 0, 1); // January 1, 501 BC
const long = new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
era: 'long'
});
console.log(long.format(bcDate)); // "January 1, 501 Before Christ"
const short = new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
era: 'short'
});
console.log(short.format(bcDate)); // "January 1, 501 BC"
long 值会在公元前日期下显示 "Before Christ"。short 值会显示 "BC"。年份以正数显示,纪元指示符用于区分其是在公元 1 年之前还是之后。
处理公元前日期时需要特别注意,因为 JavaScript Date 对象在处理远古日期时存在局限性。1582 年格里高利历标准化之前的历史日期为近似值,1 年之前的日期采用的是当时并不存在的历法系统。
在日本历中显示纪元
日本历法采用以天皇在位期间更替的年号制度。当前年号为“令和”,自 2019 年开始。前一个年号为“平成”,从 1989 年持续到 2019 年。
你可以在 locale 标识符中使用 Unicode 扩展 -u-ca-japanese 来指定日本历法。
const date = new Date('2024-10-15');
const long = new Intl.DateTimeFormat('ja-JP-u-ca-japanese', {
year: 'numeric',
month: 'long',
day: 'numeric',
era: 'long'
});
console.log(long.format(date)); // "令和6年10月15日"
const short = new Intl.DateTimeFormat('ja-JP-u-ca-japanese', {
year: 'numeric',
month: 'long',
day: 'numeric',
era: 'short'
});
console.log(short.format(date)); // "令和6年10月15日"
const narrow = new Intl.DateTimeFormat('ja-JP-u-ca-japanese', {
year: 'numeric',
month: 'long',
day: 'numeric',
era: 'narrow'
});
console.log(narrow.format(date)); // "R6年10月15日"
long 和 short 两个值都会显示“令和”以及该年号下的年份。例如,2024 年是令和第 6 年。narrow 值会以紧凑缩写形式显示为“R”。
显示的年份不是公历年,而是当前天皇年号下的纪年。每个年号的年份都从 1 开始重新计数。
在佛历中显示纪元
佛历从公元前 543 年佛陀圆寂之年开始计年。佛历 2567 年对应公历 2024 年。
你可以在 locale 标识符中使用 Unicode 扩展 -u-ca-buddhist 来指定佛历。
const date = new Date('2024-10-15');
const long = new Intl.DateTimeFormat('th-TH-u-ca-buddhist', {
year: 'numeric',
month: 'long',
day: 'numeric',
era: 'long'
});
console.log(long.format(date)); // "15 ตุลาคม พุทธศักราช 2567"
const short = new Intl.DateTimeFormat('th-TH-u-ca-buddhist', {
year: 'numeric',
month: 'long',
day: 'numeric',
era: 'short'
});
console.log(short.format(date)); // "15 ตุลาคม พ.ศ. 2567"
long 值会显示“พุทธศักราช”(佛历)作为完整纪元名称。short 值会显示“พ.ศ.”作为缩写形式。2567 年表示佛历年份,对应公历 2024 年。
佛历在泰国、柬埔寨、老挝、缅甸和斯里兰卡等国家广泛使用。
不同本地化环境下的纪元格式差异
不同的本地化环境会对同一纪元使用不同的术语和缩写。公历纪元会以各自语言和风格显示,适应不同 locale 的需求。
const date = new Date('2024-10-15');
const options = {
year: 'numeric',
month: 'long',
day: 'numeric',
era: 'short'
};
const en = new Intl.DateTimeFormat('en-US', options);
console.log(en.format(date)); // "October 15, 2024 AD"
const fr = new Intl.DateTimeFormat('fr-FR', options);
console.log(fr.format(date)); // "15 octobre 2024 ap. J.-C."
const de = new Intl.DateTimeFormat('de-DE', options);
console.log(de.format(date)); // "15. Oktober 2024 n. Chr."
英语使用 "AD"(Anno Domini,公元)。法语使用 "ap. J.-C."(après Jésus-Christ,意为“耶稣基督之后”)。德语使用 "n. Chr."(nach Christus,意为“基督之后”)。
纪元标识的位置也遵循本地习惯。英语通常将其放在年份之后,而其他语言环境可能有不同的放置方式。
const bcDate = new Date(-500, 0, 1);
const options = {
year: 'numeric',
month: 'long',
day: 'numeric',
era: 'short'
};
const en = new Intl.DateTimeFormat('en-US', options);
console.log(en.format(bcDate)); // "January 1, 501 BC"
const fr = new Intl.DateTimeFormat('fr-FR', options);
console.log(fr.format(bcDate)); // "1 janvier 501 av. J.-C."
const de = new Intl.DateTimeFormat('de-DE', options);
console.log(de.format(bcDate)); // "1. Januar 501 v. Chr."
法语在公元前日期中使用 "av. J.-C."(avant Jésus-Christ,意为“耶稣基督之前”)。德语使用 "v. Chr."(vor Christus,意为“基督之前”)。
常见用例
显示历史日期时需要纪元标识,以避免混淆。
const battleOfMarathon = new Date(-490, 8, 12); // September 12, 490 BC
const formatter = new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
era: 'short'
});
console.log(`Battle of Marathon: ${formatter.format(battleOfMarathon)}`);
// "Battle of Marathon: September 12, 490 BC"
在使用不同历法系统的文化语境下显示日期时,需要采用合适的历法和纪元格式。
const date = new Date('2024-10-15');
const japaneseFormatter = new Intl.DateTimeFormat('ja-JP-u-ca-japanese', {
year: 'numeric',
month: 'long',
day: 'numeric',
era: 'long'
});
console.log(`Japanese date: ${japaneseFormatter.format(date)}`);
// "Japanese date: 令和6年10月15日"
学术或历史写作中通常会同时明确显示 BC 和 AD,以保证跨时间段的一致性。
const dates = [
new Date(-2500, 0, 1), // 2501 BC
new Date(-500, 0, 1), // 501 BC
new Date(500, 0, 1), // 500 AD
new Date(1500, 0, 1) // 1500 AD
];
const formatter = new Intl.DateTimeFormat('en-US', {
year: 'numeric',
era: 'short'
});
dates.forEach(date => {
console.log(formatter.format(date));
});
// "2501 BC"
// "501 BC"
// "500 AD"
// "1500 AD"
总结
在 era 选项中,Intl.DateTimeFormat 会显示诸如 AD、BC 或其他历法系统的纪元名称。该选项接受三个值:long 表示完整纪元名称(如 "Anno Domini"),short 表示缩写(如 "AD"),narrow 表示最简形式(如 "A")。
在 JavaScript Date 构造函数中,BC 日期需要使用负数年份。格式化输出时,年份以正数显示,并通过纪元标识区分其是在 1 年之前还是之后。
其他历法系统有各自的纪元。日本历法使用以天皇年号命名的纪元,如令和。佛历以公元前 543 年为纪元起点。可以通过在区域标识符中使用 Unicode 扩展来指定历法系统。
不同的地区会使用不同的术语来表示同一历史时期。英文使用 "AD" 和 "BC",法文使用 "ap. J.-C." 和 "av. J.-C.",德文使用 "n. Chr." 和 "v. Chr."。格式化程序会根据每个地区自动应用相应的术语和位置。