如何显示公元前/公元或其他时代指示符?

使用 Intl.DateTimeFormat 中的 era 选项显示公元、公元前以及其他日历系统中的时代名称

介绍

大多数您处理的日期都属于公历的当前纪元,因此纪元指示通常是多余的。像“2024年10月15日”这样的日期无需在末尾添加“公元”也很清楚。然而,距今两千多年前的历史日期需要纪元指示来明确年份是位于公元1年之前还是之后。

不同文化也使用带有自己纪元的不同日历系统。例如,日本日历将时间划分为以“令和”和“平成”等命名的天皇纪元。佛教日历从佛陀涅槃开始计年。伊斯兰日历的纪元始于希吉拉。

JavaScript 的 Intl.DateTimeFormat 提供了一个 era 选项,用于显示这些纪元指示。该选项适用于公历和其他日历系统,并根据区域设置的惯例自动格式化纪元。

理解日历系统中的纪元

纪元表示从某个重要事件或起点开始计算的一段时间。公历使用两个纪元:公元(AD,Anno Domini,意为“我们主的年份”)表示公元1年之后的日期,公元前(BC,Before Christ)表示公元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年。

您可以在区域标识符中使用 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日"

longshort 值都显示了“令和”年号,后面是该年号内的年份。2024年是令和年号的第6年。narrow 值以紧凑的缩写形式显示“R”。

显示的年份不是公历年份,而是当前年号内的年份。每个年号的年份从1重新开始计数。

在佛历中显示年号

佛历从公元前543年佛陀涅槃开始计年。佛历2567年对应于公历2024年。

您可以在区域标识符中使用 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年的年份。

佛历在泰国、柬埔寨、老挝、缅甸和斯里兰卡被广泛使用。

不同语言环境中的时代格式差异

不同的语言环境对同一时代使用不同的术语和缩写。公历时代会以适合每个语言环境的语言和样式显示。

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); // 公元前 490 年 9 月 12 日

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日"

学术或历史写作中通常会明确显示公元前和公元后,以在不同时期之间保持一致性。

const dates = [
  new Date(-2500, 0, 1), // 公元前 2501 年
  new Date(-500, 0, 1),  // 公元前 501 年
  new Date(500, 0, 1),   // 公元 500 年
  new Date(1500, 0, 1)   // 公元 1500 年
];

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"

摘要

Intl.DateTimeFormatera 选项用于显示时代指示符,例如公元(AD)、公元前(BC)或其他日历系统中的时代名称。该选项接受三个值:long 表示完整的时代名称,例如“Anno Domini”(公元);short 表示缩写形式,例如“AD”;narrow 表示最紧凑的形式,例如“A”。

对于公元前的日期,JavaScript 的 Date 构造函数需要使用负年份。格式化的输出会将年份显示为正数,并通过时代指示符表明其是在公元 1 年之前还是之后。

其他日历系统有其自己的时代。例如,日本日历使用命名的皇室时代,如令和;佛教日历使用一个始于公元前 543 年的单一时代。您可以通过在区域标识符中使用 Unicode 扩展来指定日历系统。

不同的区域对同一时代使用不同的术语。例如,英语使用“AD”和“BC”,法语使用“ap. J.-C.”和“av. J.-C.”,德语使用“n. Chr.”和“v. Chr.”。格式化器会自动为每个区域应用适当的术语和位置。