Как отобразить год и эпоху в некатолических календарях?
Используйте опции calendar и era в Intl.DateTimeFormat, чтобы отображать годы и эпохи из исламского, еврейского, китайского, персидского и других календарных систем.
Введение
Григорианский календарь отсчитывает годы от одной начальной точки, что делает 2024 год простым числом. Другие системы календарей отсчитывают годы иначе. Исламский календарь ведет отсчет с 622 года н.э. Еврейский календарь отсчитывает годы от традиционной даты сотворения мира, произошедшей тысячи лет назад. Китайский календарь использует 60-летний цикл именованных лет вместо последовательных чисел.
Эти различные системы отсчета означают, что один и тот же момент времени имеет разные представления года в разных календарях. 15 октября 2024 года в григорианском календаре соответствует 1446 году в исламском календаре, 5785 году в еврейском календаре и 2024 году (甲辰, jiǎ-chén) в китайском календаре.
JavaScript Intl.DateTimeFormat предоставляет опции для отображения годов и эр из любой системы календарей. Опция calendar выбирает, какой календарь использовать. Опции year и era управляют тем, как отображаются год и эра. Для календарей, которые используют именованные годы вместо чисел, метод formatToParts() предоставляет доступ как к имени года, так и к соответствующему григорианскому году.
Как годы различаются в разных системах календарей
Системы календарей различаются по трем основным аспектам: откуда они начинают отсчет, как они нумеруют годы и используют ли они эры.
Григорианский календарь начинает отсчет с 1 года н.э. и увеличивается последовательно. Исламский календарь начинается с 1 года хиджры (после переселения) в 622 году н.э. Еврейский календарь начинается с 1 года в 3761 году до н.э. У каждого календаря есть своя эпоха — точка, с которой начинается отсчет лет.
Некоторые календари используют последовательные номера лет, которые увеличиваются бесконечно. Так работают григорианский, исламский, еврейский и персидский календари. Другие календари используют циклы, где имена лет повторяются. Китайский календарь использует 60-летний цикл именованных лет. Через 60 лет цикл повторяется.
Эры делят время на именованные периоды. Григорианский календарь использует до н.э. и н.э. Японский календарь использует имена императорских эр. Исламский и еврейский календари обычно используют одну эру, начавшуюся с их эпохи. Китайский календарь не использует эры таким же образом, полагаясь вместо этого на именованные годы в пределах циклов.
Отображение лет в исламском календаре
Исламский календарь отсчитывает годы от Хиджры, переселения Мухаммеда из Мекки в Медину в 622 году н.э. Исламский год 1 соответствует григорианскому 622 году. Исламский календарь использует лунные месяцы, из-за чего его годы короче григорианских. Это означает, что исламский год продвигается быстрее, и в 2024 году григорианского календаря наступит 1446 год исламского календаря.
Вы можете указать исламский календарь, используя опцию calendar со значением islamic или добавив расширение Unicode -u-ca-islamic к идентификатору локали.
const date = new Date('2024-10-15');
const formatter = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(formatter.format(date));
// "Rabi' II 12, 1446 AH"
Год отображается как 1446, что соответствует исламскому году для 15 октября 2024 года. Эра "AH" (после Хиджры) появляется автоматически при отображении исламских дат на английском языке.
Разные локали форматируют исламские даты в соответствии со своими традициями.
const date = new Date('2024-10-15');
const en = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(en.format(date));
// "Rabi' II 12, 1446 AH"
const ar = new Intl.DateTimeFormat('ar-SA', {
calendar: 'islamic',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(ar.format(date));
// "١٢ ربيع الآخر ١٤٤٦ هـ"
Арабская локаль использует арабско-индийские цифры и отображает название месяца на арабском языке. Индикатор эры изменяется на "هـ" (арабская аббревиатура для Хиджры).
Управление отображением эры в исламском календаре
Опция era управляет тем, отображается ли индикатор эры и в каком виде. Опция принимает три значения: long для полного названия эры, short для сокращения и narrow для самого компактного варианта.
const date = new Date('2024-10-15');
const long = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic',
year: 'numeric',
era: 'long'
});
console.log(long.format(date));
// "1446 Anno Hegirae"
const short = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic',
year: 'numeric',
era: 'short'
});
console.log(short.format(date));
// "1446 AH"
const narrow = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic',
year: 'numeric',
era: 'narrow'
});
console.log(narrow.format(date));
// "1446 A"
Значение long выводит "Anno Hegirae" (латинское "в год Хиджры"). Значение short выводит "AH". Значение narrow выводит просто "A".
Варианты исламского календаря
Исламский календарь имеет несколько вариантов, которые используют разные методы расчета. JavaScript поддерживает пять вариантов: islamic, islamic-civil, islamic-tbla, islamic-umalqura и islamic-rgsa.
Вариант islamic-umalqura использует официальный календарь Саудовской Аравии, основанный на астрономических наблюдениях. Вариант islamic-civil использует фиксированный арифметический расчет с чередующимися месяцами по 29 и 30 дней.
const date = new Date('2024-10-15');
const umalqura = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic-umalqura',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(umalqura.format(date));
// "Rabi' II 12, 1446 AH"
const civil = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic-civil',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(civil.format(date));
// "Rabi' II 11, 1446 AH"
Эти варианты могут давать разные номера дней для одной и той же григорианской даты, так как они используют разные методы расчета для определения границ месяцев.
Отображение лет в еврейском календаре
Еврейский календарь отсчитывает годы от традиционной даты сотворения мира в 3761 году до н.э. Это делает еврейские годы значительно больше григорианских. Еврейский год 5785 соответствует григорианскому 2024 году.
Вы можете указать еврейский календарь, используя опцию calendar со значением hebrew или добавив расширение Unicode -u-ca-hebrew к идентификатору локали.
const date = new Date('2024-10-15');
const formatter = new Intl.DateTimeFormat('en-US', {
calendar: 'hebrew',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(formatter.format(date));
// "Tishrei 13, 5785"
Год отображается как 5785, что соответствует еврейскому году для 15 октября 2024 года. Еврейский календарь является лунисолярным, то есть его месяцы следуют за луной, но годы остаются синхронизированными с солнечным годом за счет периодических високосных месяцев.
Еврейские даты в еврейской локали используют еврейские цифры и названия месяцев.
const date = new Date('2024-10-15');
const he = new Intl.DateTimeFormat('he-IL', {
calendar: 'hebrew',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(he.format(date));
// "י״ג בתשרי ה׳תשפ״ה"
Еврейская локаль отображает дату полностью на иврите, включая использование еврейских букв в качестве цифр.
Отображение лет в китайском календаре
Китайский календарь использует 60-летний цикл именованных лет вместо последовательных номеров лет. Каждое годовое имя в цикле состоит из двух иероглифов: небесного ствола и земной ветви. Год 2024 — это 甲辰 (jiǎ-chén), что в традиционной китайской астрологии означает "древесный дракон".
Поскольку китайский календарь использует именованные годы, для его отображения требуется иной подход, чем для календарей с последовательными номерами лет.
const date = new Date('2024-10-15');
const formatter = new Intl.DateTimeFormat('en-US', {
calendar: 'chinese',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(formatter.format(date));
// "Ninth Month 13, 2024(jiǎ-chén)"
Форматированный вывод включает как григорианский год 2024, так и имя года "jiǎ-chén" в скобках. Такое двойное представление помогает пользователям понять как циклическое имя года, так и соответствующий григорианский год.
Китайские даты в китайской локали отображаются с использованием китайских иероглифов.
const date = new Date('2024-10-15');
const zh = new Intl.DateTimeFormat('zh-CN', {
calendar: 'chinese',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(zh.format(date));
// "2024甲辰年九月十三"
Китайская локаль отображает имя года с использованием китайских иероглифов. Формат органично интегрирует имя года в строку даты.
Извлечение имени года и связанного года
Календари, использующие именованные годы, предоставляют две части информации: имя года в цикле и соответствующий григорианский год. Метод formatToParts() разделяет их на отдельные части.
const date = new Date('2024-10-15');
const formatter = new Intl.DateTimeFormat('zh-CN', {
calendar: 'chinese',
year: 'numeric',
month: 'long',
day: 'numeric'
});
const parts = formatter.formatToParts(date);
console.log(parts);
Массив частей включает два релевантных элемента:
[
{ type: 'relatedYear', value: '2024' },
{ type: 'yearName', value: '甲辰' },
// ... другие части
]
Часть relatedYear содержит четырехзначный григорианский год. Часть yearName содержит циклическое имя года. Такое разделение позволяет использовать одно или оба значения в пользовательском форматировании.
Вы можете извлечь эти части для создания пользовательских отображений дат.
const date = new Date('2024-10-15');
const formatter = new Intl.DateTimeFormat('zh-CN', {
calendar: 'chinese',
year: 'numeric',
month: 'long',
day: 'numeric'
});
const parts = formatter.formatToParts(date);
const yearName = parts.find(p => p.type === 'yearName')?.value;
const relatedYear = parts.find(p => p.type === 'relatedYear')?.value;
console.log(`Имя года: ${yearName}`);
// "Имя года: 甲辰"
console.log(`Григорианский год: ${relatedYear}`);
// "Григорианский год: 2024"
Этот метод работает с любым календарем, использующим именованные годы или циклы.
Отображение лет в персидском календаре
Персидский календарь, также известный как солнечный хиджри-календарь, отсчитывает годы с Хиджры в 622 году н.э., как и исламский календарь. Однако персидский календарь использует солнечные месяцы вместо лунных, что делает его по структуре более похожим на григорианский календарь.
Вы можете указать персидский календарь, используя опцию calendar со значением persian или добавив Unicode-расширение -u-ca-persian к идентификатору локали.
const date = new Date('2024-10-15');
const formatter = new Intl.DateTimeFormat('en-US', {
calendar: 'persian',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(formatter.format(date));
// "Mehr 24, 1403 AP"
Год отображается как 1403, что соответствует персидскому году для 15 октября 2024 года. Эра "AP" (Anno Persico) появляется в английском формате.
Персидские даты в персидской локали используют персидские цифры и названия месяцев.
const date = new Date('2024-10-15');
const fa = new Intl.DateTimeFormat('fa-IR', {
calendar: 'persian',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(fa.format(date));
// "۲۴ مهر ۱۴۰۳ ه.ش."
Персидская локаль отображает дату, используя персидские (фарси) символы и цифры. Индикатор эры "ه.ش." — это персидская аббревиатура для солнечной хиджри-эры.
Комбинирование опций календаря и эры
Вы можете комбинировать опции calendar и era, чтобы точно контролировать, как отображаются годы и эры в разных календарных системах. Эта комбинация дает вам точный контроль над форматированием дат.
const date = new Date('2024-10-15');
const gregorian = new Intl.DateTimeFormat('en-US', {
calendar: 'gregory',
year: 'numeric',
month: 'long',
era: 'short'
});
console.log(gregorian.format(date));
// "October 2024 AD"
const islamic = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic',
year: 'numeric',
month: 'long',
era: 'short'
});
console.log(islamic.format(date));
// "Rabi' II 1446 AH"
const hebrew = new Intl.DateTimeFormat('en-US', {
calendar: 'hebrew',
year: 'numeric',
month: 'long',
era: 'short'
});
console.log(hebrew.format(date));
// "Tishrei 5785"
Григорианские и исламские даты отображают свои индикаторы эры, так как опция era установлена. Еврейская дата не показывает индикатор эры в этом формате, так как форматирование еврейского календаря обычно его опускает.
Вы также можете смешивать локали и календари, чтобы отображать даты на одном языке, используя календарь другой культуры.
const date = new Date('2024-10-15');
const englishIslamic = new Intl.DateTimeFormat('en-US', {
calendar: 'islamic',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(englishIslamic.format(date));
// "Rabi' II 12, 1446 AH"
const arabicIslamic = new Intl.DateTimeFormat('ar-SA', {
calendar: 'islamic',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(arabicIslamic.format(date));
// "١٢ ربيع الآخر ١٤٤٦ هـ"
Оба форматировщика используют исламский календарь, но английская локаль выводит английские названия месяцев и латинские цифры, в то время как арабская локаль использует арабские названия месяцев и арабско-индийские цифры.
Отображение лет в разных календарях
Приложения, ориентированные на международную аудиторию, часто должны отображать одну и ту же дату в разных календарных системах. Вы можете создать несколько форматтеров для отображения параллельных представлений.
const date = new Date('2024-10-15');
const calendars = [
{ name: 'Григорианский', calendar: 'gregory' },
{ name: 'Исламский', calendar: 'islamic' },
{ name: 'Еврейский', calendar: 'hebrew' },
{ name: 'Персидский', calendar: 'persian' }
];
calendars.forEach(cal => {
const formatter = new Intl.DateTimeFormat('ru-RU', {
calendar: cal.calendar,
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(`${cal.name}: ${formatter.format(date)}`);
});
Это выводит:
Григорианский: 15 октября 2024 г.
Исламский: 12 Раби' II 1446 г. хиджры
Еврейский: 13 Тишрей 5785 г.
Персидский: 24 Мехр 1403 г. н.э.
Каждый календарь представляет один и тот же момент времени, используя свою собственную систему летоисчисления и обозначения эпох.
Общие случаи использования
Международные приложения должны отображать даты в тех календарных системах, которые ожидают их пользователи. Например, исламское банковское приложение отображает даты транзакций, используя исламский календарь.
const transactionDate = new Date('2024-10-15');
const formatter = new Intl.DateTimeFormat('ar-SA', {
calendar: 'islamic-umalqura',
year: 'numeric',
month: 'long',
day: 'numeric',
era: 'short'
});
console.log(`Дата транзакции: ${formatter.format(transactionDate)}`);
// "Дата транзакции: ١٢ ربيع الآخر ١٤٤٦ هـ"
Религиозные календари определяют даты праздников и обрядов. Например, приложение для еврейского календаря отображает еврейские даты для праздников.
const roshHashanah2024 = new Date('2024-10-03');
const formatter = new Intl.DateTimeFormat('he-IL', {
calendar: 'hebrew',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(`Рош ха-Шана: ${formatter.format(roshHashanah2024)}`);
// "Рош ха-Шана: א׳ בתשרי ה׳תשפ״ה"
Исторические приложения отображают даты в тех календарных системах, которые использовались в то время. Например, приложение о древней Персии отображает даты, используя персидский календарь.
const historicalDate = new Date('2024-03-20');
const formatter = new Intl.DateTimeFormat('ru-RU', {
calendar: 'persian',
year: 'numeric',
month: 'long',
day: 'numeric',
era: 'long'
});
console.log(`Персидский Новый год: ${formatter.format(historicalDate)}`);
// "Персидский Новый год: 1 Фарвардина 1403 года нашей эры"
Резюме
Некоторые некатолические календари отсчитывают годы от разных начальных точек и используют различные системы нумерации. Исламский календарь ведет отсчет с 622 года н.э. и в настоящее время показывает годы около 1446. Еврейский календарь отсчитывает с 3761 года до н.э. и показывает годы около 5785. Китайский календарь использует 60-летний цикл именованных лет вместо последовательных чисел.
JavaScript поддерживает эти календарные системы через опцию calendar в Intl.DateTimeFormat. Возможные значения включают islamic, hebrew, chinese, persian и другие. Опция year управляет отображением года, а опция era управляет отображением и форматом индикатора эпохи.
Календари, использующие именованные годы, предоставляют два элемента информации через formatToParts(). Часть yearName содержит циклическое имя года. Часть relatedYear содержит соответствующий год по григорианскому календарю. Это позволяет приложениям отображать одно или оба значения.
Разные локали форматируют один и тот же календарь по-разному. Исламский календарь отображается на английском языке с латинскими цифрами и на арабском языке с арабско-индийскими цифрами. Форматирование автоматически адаптируется к конвенциям локали, сохраняя систему нумерации лет календаря.