如何显示公历、希伯来历、伊斯兰历等日历名称?

使用 JavaScript 的 Intl.DisplayNames API 以任意语言显示易于理解的日历系统名称

简介

不同的文化和宗教采用不同的日历系统来记录日期和安排时间。虽然公历在世界许多地区被广泛使用,但其他日历系统也常用于宗教活动、文化节日和日常生活。希伯来历在以色列及全球犹太社区中使用。伊斯兰历指导穆斯林的宗教实践。佛历则在泰国及东南亚其他国家使用。

面向国际用户的应用需要允许用户选择自己偏好的日历系统。日期选择器、设置界面和日程工具会显示日历名称,方便用户选择符合需求的系统。与其显示像 "gregory" 或 "islamic-umalqura" 这样的代码,不如直接展示 "公历" 或 "乌姆·盖拉历" 这样的易懂名称。

JavaScript 的 Intl.DisplayNames API 可以将日历系统代码转换为易于理解的名称。该 API 会自动处理翻译,无需手动维护翻译文件,即可根据用户的语言显示日历名称。

什么是日历代码

日历代码是用于表示不同日历系统的简短字符串标识符。JavaScript 在内部使用这些标准化代码来识别日历类型。

常见的日历代码包括:

  • gregory 表示公历
  • hebrew 表示希伯来历
  • islamic 表示伊斯兰历
  • buddhist 表示佛历
  • chinese 表示中国农历
  • japanese 表示日本历

这些代码遵循 Unicode 区域标识符规范。它们始终为小写,并在需要时使用连字符分隔单词,例如 islamic-umalquraislamic-civil

Intl.DisplayNames 如何与日历配合使用

Intl.DisplayNames 构造函数会创建一个对象,将代码转换为可读文本。你需要指定输出语言的 locale 以及要转换的代码类型。

要显示日历名称,需要将 "calendar" 作为 type 传递:

const displayNames = new Intl.DisplayNames('en', { type: 'calendar' });

第一个参数是 locale 代码,例如 'en'(英语)或 'fr'(法语)。第二个参数是 options 对象,你可以在其中设置 type: 'calendar'

获得 DisplayNames 对象后,可以使用其 of() 方法将日历代码转换为名称:

const calendarName = displayNames.of('gregory');
console.log(calendarName); // "Gregorian Calendar"

用英语显示日历名称

以下是在英语中显示公历、希伯来历和伊斯兰历名称的方法:

const displayNames = new Intl.DisplayNames('en', { type: 'calendar' });

console.log(displayNames.of('gregory')); // "Gregorian Calendar"
console.log(displayNames.of('hebrew')); // "Hebrew Calendar"
console.log(displayNames.of('islamic')); // "Islamic Calendar"

你可以通过将任意受支持的日历代码传递给 of() 方法来显示对应的日历名称:

const displayNames = new Intl.DisplayNames('en', { type: 'calendar' });

console.log(displayNames.of('buddhist')); // "Buddhist Calendar"
console.log(displayNames.of('chinese')); // "Chinese Calendar"
console.log(displayNames.of('japanese')); // "Japanese Calendar"
console.log(displayNames.of('persian')); // "Persian Calendar"

伊斯兰历有多种不同的计算方法变体:

const displayNames = new Intl.DisplayNames('en', { type: 'calendar' });

console.log(displayNames.of('islamic')); // "Islamic Calendar"
console.log(displayNames.of('islamic-umalqura')); // "Umm al-Qura Calendar"
console.log(displayNames.of('islamic-civil')); // "Islamic Civil Calendar"
console.log(displayNames.of('islamic-tbla')); // "Islamic Tabular Calendar"

获取所有可用的日历系统

JavaScript 提供了 17 种日历系统。你可以通过 Intl.supportedValuesOf() 以编程方式获取完整列表:

const calendars = Intl.supportedValuesOf('calendar');
console.log(calendars);

这将返回一个包含所有受支持日历代码的数组:

[
  'buddhist',
  'chinese',
  'coptic',
  'dangi',
  'ethioaa',
  'ethiopic',
  'gregory',
  'hebrew',
  'indian',
  'islamic',
  'islamic-umalqura',
  'islamic-tbla',
  'islamic-civil',
  'islamic-rgsa',
  'iso8601',
  'japanese',
  'persian',
  'roc'
]

你可以遍历该数组以显示所有日历名称:

const calendars = Intl.supportedValuesOf('calendar');
const displayNames = new Intl.DisplayNames('en', { type: 'calendar' });

calendars.forEach(calendar => {
  console.log(`${calendar}: ${displayNames.of(calendar)}`);
});

输出结果为:

buddhist: Buddhist Calendar
chinese: Chinese Calendar
coptic: Coptic Calendar
dangi: Dangi Calendar
ethioaa: Ethiopic Amete Alem Calendar
ethiopic: Ethiopic Calendar
gregory: Gregorian Calendar
hebrew: Hebrew Calendar
indian: Indian National Calendar
islamic: Islamic Calendar
islamic-umalqura: Umm al-Qura Calendar
islamic-tbla: Islamic Tabular Calendar
islamic-civil: Islamic Civil Calendar
islamic-rgsa: Islamic Calendar (Saudi Arabia)
iso8601: ISO-8601 Calendar
japanese: Japanese Calendar
persian: Persian Calendar
roc: Minguo Calendar

在不同语言中本地化日历名称

日历名称会根据你在 locale 参数中指定的语言显示。这样可以让用户以其偏好的语言查看日历名称。

以阿拉伯语显示日历名称:

const displayNames = new Intl.DisplayNames('ar', { type: 'calendar' });

console.log(displayNames.of('gregory')); // "التقويم الميلادي"
console.log(displayNames.of('hebrew')); // "التقويم العبري"
console.log(displayNames.of('islamic')); // "التقويم الهجري"

以法语显示日历名称:

const displayNames = new Intl.DisplayNames('fr', { type: 'calendar' });

console.log(displayNames.of('gregory')); // "calendrier grégorien"
console.log(displayNames.of('hebrew')); // "calendrier hébraïque"
console.log(displayNames.of('islamic')); // "calendrier musulman"

以希伯来语显示日历名称:

const displayNames = new Intl.DisplayNames('he', { type: 'calendar' });

console.log(displayNames.of('gregory')); // "לוח השנה הגרגוריאני"
console.log(displayNames.of('hebrew')); // "לוח השנה העברי"
console.log(displayNames.of('islamic')); // "לוח השנה ההיג'רי"

以中文显示日历名称:

const displayNames = new Intl.DisplayNames('zh', { type: 'calendar' });

console.log(displayNames.of('gregory')); // "公历"
console.log(displayNames.of('hebrew')); // "希伯来历"
console.log(displayNames.of('islamic')); // "伊斯兰历"

浏览器会自动处理所有翻译。你无需翻译文件或手动管理字符串。

构建日历选择下拉菜单

以下是创建一个让用户选择日历系统的下拉菜单的方法:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Calendar Selector</title>
</head>
<body>
  <label for="calendar-select">Choose a calendar:</label>
  <select id="calendar-select"></select>

  <script>
    const userLocale = navigator.language || 'en';
    const displayNames = new Intl.DisplayNames(userLocale, { type: 'calendar' });
    const calendars = Intl.supportedValuesOf('calendar');
    const selectElement = document.getElementById('calendar-select');

    calendars.forEach(calendar => {
      const option = document.createElement('option');
      option.value = calendar;
      option.textContent = displayNames.of(calendar);
      selectElement.appendChild(option);
    });

    selectElement.addEventListener('change', (event) => {
      console.log('Selected calendar:', event.target.value);
    });
  </script>
</body>
</html>

此代码实现了以下功能:

  1. 使用 navigator.language 获取用户的浏览器 locale
  2. 使用用户的 locale 创建 DisplayNames 对象
  3. 获取所有可用的日历代码
  4. 为每个日历创建一个 option 元素
  5. 将 option 文本设置为本地化的日历名称
  6. 添加事件监听器以处理日历选择

下拉菜单会自动以用户的语言显示日历名称。使用阿拉伯语浏览器的用户会看到阿拉伯语日历名称,使用法语浏览器的用户会看到法语日历名称。

何时显示日历名称

在以下场景中显示日历名称:

  • 用户在设置页面选择首选日历系统
  • 支持多种日历系统的日期选择组件
  • 用户在事件创建表单中指定要使用的日历
  • 存储日历偏好的用户个人资料页面
  • 跨不同日历系统进行调度的应用程序
  • 涉及特定日历的宗教或文化类应用

显示日历名称可以让您的应用程序对使用非公历系统的用户更加友好。这可以消除应用在日期和事件中所用日历系统的歧义。

通过 Intl.DisplayNames API 结合 type: 'calendar',您可以即时获取本地化的日历名称,无需维护翻译文件或日历系统元数据。