dateTime

Форматирование дат с помощью объекта DateTimeFormat

Форматирование даты с помощью конструктора Intl.DateTimeFormat

Различные части мира имеют разные форматы даты. Чтобы справиться с этим, JavaScript имеет конструктор Intl.DateTimeFormat, позволяющий нам форматировать даты в разные форматы в соответствии с разными локациями.

Это означает, что мы можем форматировать даты для разных мест без необходимости самим манипулировать строками дат, делая нашу жизнь намного проще. Конструктор Intl.DateTimeFormat принимает строку локации в качестве аргумента.

С помощью DateTimeFormat, созданного конструктором, мы можем использовать метод экземпляра format, который принимает объект Date для возврата строки даты с датой, отформатированной для локали, которую вы указали в конструкторе Intl.DateTimeFormat.

Конструктор и метод форматирования

Чтобы использовать конструктор Intl.DateTimeFormat, мы можем использовать его, как в следующем примере:

const date = new Date(2019, 0, 1, 0, 0, 0);
console.log(new Intl.DateTimeFormat('en-US').format(date));
console.log(new Intl.DateTimeFormat('fr-ca').format(date));
console.log(new Intl.DateTimeFormat(['ban', 'de']).format(date));
 

В приведенном выше примере мы создали объект Date, а затем использовали конструктор Intl.DateTimeFormat, в котором одна или несколько локаций были переданы в виде строки.

Затем мы вызвали format, передав объект Date. Первый пример будет записан 1/1/2019, так как США используют формат даты MM / DD / YYYY.

Во втором примере будут записываться 2019–01–01, поскольку даты французско-канадского языка представлены в формате ГГГГ-ММ-ДД. В третьем примере используется массив, в котором есть несколько локаций, а справа - запасные локали для левых.

В нашем примере, так как у нас есть недопустимый ban строки локали в первой записи массива, нам, вместо этого, необходимо используем немецкий формат даты de для форматирования объекта Date, поэтому мы получаем 1.1.2019, так как Германия использует DD.MM.YYYY формат даты.

Как видно из приведенных выше примеров, конструктор Intl.DateTimeFormat принимает строку локали или массив строк локали. Он также принимает ключи расширения Unicode для строк локали, так что мы можем добавить их в наш языковой тег.

Поддерживаются дополнительные клавиши nu для настройки системы нумерации, ca для календаря для форматирования даты и hc для часового цикла.

Возможными значениями nu могут быть arab, arabext, bali, beng, deva, fullwide, gujr, guru, hanidec, khmr, knda, laoo, latn, limb, mlym, mong, mymr, orya, tamldec, telu, thai, tibt.

Возможными значениями ca могут быть buddhist, chinese, coptic, ethiopia, ethiopic, gregory, hebrew, indian, islamic, iso8601, japanese, persian, roc.

Возможными значениями hc могут быть h11, h12, h23, h24. Например, чтобы форматировать даты согласно буддийскому календарю, мы можем написать:

const date = new Date(2019, 0, 1, 0, 0, 0);
console.log(new Intl.DateTimeFormat('en-US-u-ca-buddhist').format(date));
 

Тогда мы получим 1/1/2562 в console.log, поскольку год 0 буддийского календаря в 545 году до нашей эры.

Второй аргумент принимает объект, который позволяет нам устанавливать различные параметры в его свойствах для форматирования даты.

Опция localeMatcher указывает используемый алгоритм сопоставления локаций. Возможные значения: lookup и best fit. Алгоритм поиска ищет локали, пока не найдет ту, которая соответствует набору символов сравниваемых строк.

best fit находит локаль, возможно, больше подходит, чем алгоритм lookup. Опция timeZone позволяет нам установить часовой пояс, который форматирует дату.

Самая базовая реализация распознает только UTC, но другие могут распознавать имена часовых поясов IANA в базе данных часовых поясов IANA, например Asia/Shanghai, Asia/Kolkata, America/New_York.

Параметр hour12 определяет 12-часовой или 24-часовой формат времени. Значение по умолчанию зависит от локали. Он переопределяет тег языка hc в первом аргументе.

Это значение true или false, где true означает форматирование времени даты с 12-часовым временем. Параметр hourCycle имеет возможные значения h11, h12, h23, h24 и переопределяет тег языка hc. hour12 имеет приоритет над этой опцией, если она указана.

Свойство formatMatcher указывает используемый алгоритм сопоставления. Возможные значения basic и best fit. best fit - дефолтное значение.

Следующие подмножества даты и времени необходимы для соответствия объекта даты правильному формату:

• weekday, year, month, day, hour, minute, second

• weekday, year, month, day

• year, month, day

• year, month

• month, day

• hour, minute, second

• hour, minute

weekday - представляет значение дня недели, возможные значения:

• long (напр., Friday)

• short (напр., Fri)

• “narrow" (напр., T). Обратите внимание, что два дня недели могут иметь одинаковый стиль для некоторых языков. Например, стиль narrow Tuesday также T.

era - представляет эпоху, возможные значения:

• long (напр., Anno Domini)

• short (напр., AD)

• narrow (напр., A)

year - представляет год, возможные значения:

• numeric (напр., 2019)

• 2-digit (напр., 19)

month - представляет месяц, возможные значения:

• numeric (напр., 2)

• 2-digit (напр., 02)

• long (напр., February)

• short (напр., Feb)

• narrow (напр., M). Обратите внимание, что два месяца могут иметь один и тот же стиль “narrow для некоторых локаций. (напр., стиль “narrow для May так же M)

• day - представляет день, возможные значения:

• numeric (напр., 2)

• 2-digit (напр., 02)

hour - представляет час, возможные значения numeric, 2-digit.

minute - представляет минуту, возможные значения, возможные значения numeric, 2-digit.

second - представляет час, возможные значения numeric, 2-digit.

timeZoneName - представляет название часового пояса, возможные значения

• long (напр., Pacific Standard Time)

• short (напр., GMT-8)

Значение по умолчанию для каждого свойства компонента выше undefined, но если все компоненты undefined, то year, month, и day считаются numeric.

Пример использования опций приведен ниже:

const date = new Date(2019, 0, 1, 0, 0, 0);
const options = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
};
console.log(new Intl.DateTimeFormat('en-ca', options).format(date));
 

В приведенном выше коде мы устанавливаем локацию на канадский английский, а в options мы устанавливаем weekday в long, year в numeric, month в long и day в numeric, так что мы получаем полное название дня недели на английском языке, год как число, месяц с полным именем и день как число.

В файле console.log будет записано “Tuesday, January 1, 2019”. В приведенном выше примере может быть добавлен часовой пояс, как в следующем примере:

const date = new Date(2019, 0, 1, 0, 0, 0);
const options = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
timeZone: 'America/Vancouver',
timeZoneName: 'long'
};
console.log(new Intl.DateTimeFormat('en-ca', options).format(date));
 

В приведенном выше примере мы добавили timeZone и timeZoneLong, чтобы отобразить часовой пояс и получить “Tuesday, January 1, 2019, Pacific Standard Time”.

Конструктор Intl.DateTimeFormat одинаково хорошо обрабатывает неанглийский формат. Например, если мы хотим отформатировать дату на китайском языке, мы можем изменить локацию и оставить параметры такими же, как указано выше, как в следующем коде:

const date = new Date(2019, 0, 1, 0, 0, 0);
const options = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
timeZone: 'America/Vancouver',
timeZoneName: 'long'
};
console.log(new Intl.DateTimeFormat('zh-Hant', options).format(date));
 

Затем мы получаем “2019年1月1日 星期二 太平洋標準時間”, что совпадает с “Tuesday, January 1, 2019, Pacific Standard Time” на традиционном китайском языке.

Другие методы

Instance объекта-конструктора Intl.DateTimeFormat также имеют несколько методов Instance в дополнение к методу format().

Он также имеет метод formatToParts() для возврата массива объектов, представляющих различные части строки даты. Метод resolvedOptions() возвращает новый объект со свойствами, отражающими локаль и параметры форматирования, которые мы вычислили во время инициализации объекта.

Метод formatRange() принимает два объекта Date в качестве аргументов и форматирует диапазон дат самым кратким образом, основываясь на локали и опциях, предоставляемых при создании экземпляра объекта DateTimeFormat.

Наконец, у него есть метод formatRangeToParts(), который принимает два объекта Date в качестве аргументов и форматирует диапазон дат самым кратким образом на основе локали и параметров, предоставленных, когда мы создаем экземпляр объекта DateTimeFormat и возвращаем части даты и времени в массиве объектов.

Например, если у нас есть следующий код, который вызывает метод formatRangeToParts():

const startDate = new Date(2019, 0, 1, 0, 0, 0);
const endDate = new Date(2019, 0, 2, 0, 0, 0);
const options = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
timeZone: 'America/Vancouver',
timeZoneName: 'long'
};
const dateRange = new Intl.DateTimeFormat('zh-Hant', options).formatRangeToParts(startDate, endDate)
console.log(dateRange);
 

Затем мы получаем следующие части даты и времени:

[
{
"type": "year",
"value": "2019",
"source": "startRange"
},
{
"type": "literal",
"value": "年",
"source": "startRange"
},
{
"type": "month",
"value": "1",
"source": "startRange"
},
{
"type": "literal",
"value": "月",
"source": "startRange"
},
{
"type": "day",
"value": "1",
"source": "startRange"
},
{
"type": "literal",
"value": "日 ",
"source": "startRange"
},
{
"type": "weekday",
"value": "星期二",
"source": "startRange"
},
{
"type": "literal",
"value": " ",
"source": "startRange"
},
{
"type": "timeZoneName",
"value": "太平洋標準時間",
"source": "startRange"
},
{
"type": "literal",
"value": " – ",
"source": "shared"
},
{
"type": "year",
"value": "2019",
"source": "endRange"
},
{
"type": "literal",
"value": "年",
"source": "endRange"
},
{
"type": "month",
"value": "1",
"source": "endRange"
},
{
"type": "literal",
"value": "月",
"source": "endRange"
},
{
"type": "day",
"value": "2",
"source": "endRange"
},
{
"type": "literal",
"value": "日 ",
"source": "endRange"
},
{
"type": "weekday",
"value": "星期三",
"source": "endRange"
},
{
"type": "literal",
"value": " ",
"source": "endRange"
},
{
"type": "timeZoneName",
"value": "太平洋標準時間",
"source": "endRange"
}
]
 

Как мы можем видеть из вывода консоли выше, мы получаем части даты и времени в каждой записи массива, причем части startDate идут первыми, а части endDate - в последних частях массива.

Если мы вызываем метод formatRange(), как в коде ниже:

const startDate = new Date(2019, 0, 1, 0, 0, 0);
const endDate = new Date(2019, 0, 2, 0, 0, 0);
const options = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
timeZone: 'America/Vancouver',
timeZoneName: 'long'
};
const dateRange = new Intl.DateTimeFormat('en', options).formatRange(startDate, endDate)
console.log(dateRange);
 

Тогда мы получим:

"Tuesday, January 1, 2019, Pacific Standard Time – Wednesday, January 2, 2019, Pacific Standard Time"

Из console.log.

Чтобы вызвать метод resolvedOptions, мы можем написать код ниже:

const date = new Date(2019, 0, 1, 0, 0, 0);
const options = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
timeZone: 'America/Vancouver',
timeZoneName: 'long'
};
const resolvedOptions = new Intl.DateTimeFormat('en', options).resolvedOptions(date)
console.log(resolvedOptions);
 

Затем мы получаем параметры, которые мы передали для форматирования даты:

{
"locale": "en",
"calendar": "gregory",
"numberingSystem": "latn",
"timeZone": "America/Vancouver",
"weekday": "long",
"year": "numeric",
"month": "long",
"day": "numeric",
"timeZoneName": "long"
}
 

В console.log.

Чтобы использовать метод formatToParts(), мы можем использовать его как метод format(), как в следующем коде:

const date = new Date(2019, 0, 1, 0, 0, 0);
const options = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
timeZone: 'America/Vancouver',
timeZoneName: 'long'
};
const dateParts = new Intl.DateTimeFormat('en', options).formatToParts(date)
console.log(dateParts);
 

Затем мы получаем части отформатированной даты в console.log, как показано ниже:

[
{
"type": "weekday",
"value": "Tuesday"
},
{
"type": "literal",
"value": ", "
},
{
"type": "month",
"value": "January"
},
{
"type": "literal",
"value": " "
},
{
"type": "day",
"value": "1"
},
{
"type": "literal",
"value": ", "
},
{
"type": "year",
"value": "2019"
},
{
"type": "literal",
"value": ", "
},
{
"type": "timeZoneName",
"value": "Pacific Standard Time"
}
]
 

Как мы видим, конструктор Intl.DateTimeFormat очень полезен для форматирования дат для разных локалей. Он существенно упрощает работу с форматированием дат.

Конструктор принимает одну или несколько локалей в качестве первого аргумента и различные параметры в качестве второго аргумента.

Он может форматировать даты в одну строку, а также форматировать их и разбивать на части. Это экономит много времени при форматировании дат для разных регионов, так как нам не нужно выполнять какие-либо манипуляции со строками даты.