Кратко
СкопированоIntl
— объект, содержащий функции форматирования даты и времени с учётом локали.
Конструктор объекта принимает следующие параметры:
locales
— код или массив идентификаторов локалей. Элементы этого массива могут обозначать язык, например,en
, язык и регион, к примеру,en
. Также используют дополнительные обозначения, например,- U S zh
(китайский язык, упрощённый китайский скрипт и регион Китай).- Hans - C N options
— дополнительные опции.
Как понять
СкопированоФорматирование объекта Date
— настоящая головная боль. Чтобы красиво отображать дату и время, не обязательно подключать тяжеловесные сторонние библиотеки. Можно воспользоваться встроенным объектом Intl
.
Этот способ форматирования поддерживается всеми современными браузерами.
Пример
СкопированоЧтобы отобразить дату несколькими способами, создадим объект даты при помощи статического метода
. Этот метод возвращает количество миллисекунд с момента начала Unix-эпохи.
работает со всемирным координатным временем (UTC).
const date = new Date(Date.UTC(2020, 11, 20, 3, 23, 16, 738))
const date = new Date(Date.UTC(2020, 11, 20, 3, 23, 16, 738))
Стандартное форматирование в зависимости от локали:
console.log(new Intl.DateTimeFormat('en-US').format(date))// 12/20/2020
console.log(new Intl.DateTimeFormat('en-US').format(date)) // 12/20/2020
console.log(new Intl.DateTimeFormat('ru', { weekday: 'short', year: '2-digit', month: 'long', day: 'numeric'}) .format(date))// Вс, 20 декабря 20 г.
console.log(new Intl.DateTimeFormat('ru', { weekday: 'short', year: '2-digit', month: 'long', day: 'numeric'}) .format(date) ) // Вс, 20 декабря 20 г.
Укажем формат даты и времени, используя параметр style
(full
, long
, medium
, short
):
console.log(new Intl.DateTimeFormat('en-GB', { dateStyle: 'full', timeStyle: 'long', timeZone: 'Australia/Sydney'}) .format(date))// Sunday, 20 December 2020 at 14:23:16 GMT+11
console.log(new Intl.DateTimeFormat('en-GB', { dateStyle: 'full', timeStyle: 'long', timeZone: 'Australia/Sydney'}) .format(date) ) // Sunday, 20 December 2020 at 14:23:16 GMT+11
Как пишется
СкопированоСоздадим экземпляр:
const formattedDate = new Intl.DateTimeFormat('ru').format(date)
const formattedDate = new Intl.DateTimeFormat('ru').format(date)
Опции
Скопированоtime
— значение часового пояса.Zone UTC
,America
,/ New _ York Europe
и т. д.;/ Paris calendar
— значение выбранного календаря.chinese
,gregory
,indian
и т. д.;numbering
— используемая система счисления.System arab
,beng
,latin
и т. д.;locale
— алгоритм для согласования выбранной локали:Matcher lookup
— поиск следует алгоритму поиска, определённому в BCP 47;best fit
(наилучший, подходящий) — позволяет среде выполнения выбрать локаль.
format
— алгоритм для форматирования.Matcher basic
,best fit
;hour12
— 12-часовой формат, если значениеtrue
;hour
— часовой формат.Cycle h11
,h12
,h23
,h24
;date
— стиль форматирования даты.Style full
,long
,medium
,short
;weekday
— день недели.long
,short
,narrow
;day
— день месяца.numeric
,2
;- digit month
— месяц.numeric
,2
,- digit long
,short
,narrow
;year
— год.numeric
,2
;- digit era
— эпоха.long
,short
,narrow
;time
— стиль форматирования времени.Style full
,long
,medium
,short
;hour
— часы.numeric
,2
;- digit minute
— минуты.numeric
,2
;- digit second
— секунды.numeric
,2
;- digit day
— часть дня (утро, вечер и другое).Period narrow
,short
,long
;time
— название часового пояса (UTC, PTC).Zone Name long
,short
.
Методы
СкопированоIntl
— геттер, который форматирует дату в соответствии с языковым стандартом и параметрами форматирования объекта.
Возвратим текущую дату в кратком виде (date
) в виде строки.
const date = Date.now()const formatter = new Intl.DateTimeFormat('ru', { weekday: 'long', year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric', hour12: true, timeZone: 'UTC'})formatter.format(date)// суббота, 27.05.2023 г., 10:55:18 PM
const date = Date.now() const formatter = new Intl.DateTimeFormat('ru', { weekday: 'long', year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric', hour12: true, timeZone: 'UTC' }) formatter.format(date) // суббота, 27.05.2023 г., 10:55:18 PM
Intl
— форматирует передаваемую строку по частям с учётом DateTime
. Возвращает массив объектов, представляющих строку даты в частях, которые можно использовать для настраиваемого форматирования с учётом локали.
formatter.formatToParts(date)
formatter.formatToParts(date)
В консоли мы получим следующее:
[ {type: 'weekday', value: 'суббота'}, {type: 'literal', value: ', '}, {type: 'day', value: '27'}, {type: 'literal', value: '.'}, {type: 'month', value: '05'}, {type: 'literal', value: '.'}, {type: 'year', value: '2023'}, {type: 'literal', value: ' г., '}, {type: 'hour', value: '10'}, {type: 'literal', value: ':'}, {type: 'minute', value: '55'}, {type: 'literal', value: ':'}, {type: 'second', value: '18'}, {type: 'literal', value: ' '}, {type: 'dayPeriod', value: 'PM'}]
[ {type: 'weekday', value: 'суббота'}, {type: 'literal', value: ', '}, {type: 'day', value: '27'}, {type: 'literal', value: '.'}, {type: 'month', value: '05'}, {type: 'literal', value: '.'}, {type: 'year', value: '2023'}, {type: 'literal', value: ' г., '}, {type: 'hour', value: '10'}, {type: 'literal', value: ':'}, {type: 'minute', value: '55'}, {type: 'literal', value: ':'}, {type: 'second', value: '18'}, {type: 'literal', value: ' '}, {type: 'dayPeriod', value: 'PM'} ]
Intl
— возвращает новый объект со свойствами, отражающими локаль и параметры форматирования, которые вычислены при инициализации объекта.
{ calendar: 'gregory', day: '2-digit', hour: 'numeric', hour12: true, hourCycle: 'h11', locale: 'ru', minute: '2-digit', month: '2-digit', numberingSystem: 'latn', second: '2-digit', timeZone: 'UTC', weekday: 'long', year: 'numeric'}
{ calendar: 'gregory', day: '2-digit', hour: 'numeric', hour12: true, hourCycle: 'h11', locale: 'ru', minute: '2-digit', month: '2-digit', numberingSystem: 'latn', second: '2-digit', timeZone: 'UTC', weekday: 'long', year: 'numeric' }
Intl
— получает две даты и форматирует их диапазон самым кратким образом на основе языкового стандарта и параметров, предоставленных при создании экземпляра DateTime
.
const date1 = new Date(Date.UTC(2018, 0, 10, 10, 0, 0))const currentDate = Date.now()const fmt1 = new Intl.DateTimeFormat('en', { year: '2-digit', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric',})console.log(fmt1.formatRange(date1, currentDate))// 1/10/18, 1:00 PM – 5/28/23, 2:08 AM
const date1 = new Date(Date.UTC(2018, 0, 10, 10, 0, 0)) const currentDate = Date.now() const fmt1 = new Intl.DateTimeFormat('en', { year: '2-digit', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', }) console.log(fmt1.formatRange(date1, currentDate)) // 1/10/18, 1:00 PM – 5/28/23, 2:08 AM
Intl
— получает две даты и возвращает массив объектов, содержащих токены. Они зависят от языкового стандарта и представляют каждую часть отформатированного диапазона дат. Возвращает формат, аналогичный format
.
const date1 = new Date(Date.UTC(2018, 0, 10, 10, 0, 0))const currentDate = Date.now()const dateTimeFormat = new Intl.DateTimeFormat('en', { hour: 'numeric', minute: 'numeric'})const parts = dateTimeFormat.formatRangeToParts(date1, currentDate)for (const part of parts) { console.log(part)}
const date1 = new Date(Date.UTC(2018, 0, 10, 10, 0, 0)) const currentDate = Date.now() const dateTimeFormat = new Intl.DateTimeFormat('en', { hour: 'numeric', minute: 'numeric' }) const parts = dateTimeFormat.formatRangeToParts(date1, currentDate) for (const part of parts) { console.log(part) }
В консоли увидим следующее:
[ {type: 'month', value: '1', source: 'startRange'}, {type: 'literal', value: '/', source: 'startRange'}, {type: 'day', value: '10', source: 'startRange'}, {type: 'literal', value: '/', source: 'startRange'}, {type: 'year', value: '2018', source: 'startRange'}, {type: 'literal', value: ', ', source: 'startRange'}, {type: 'hour', value: '1', source: 'startRange'}, {type: 'literal', value: ':', source: 'startRange'}, {type: 'minute', value: '00', source: 'startRange'}, {type: 'literal', value: ' ', source: 'startRange'}, {type: 'dayPeriod', value: 'PM', source: 'startRange'}, {type: 'literal', value: ' – ', source: 'shared'}, {type: 'month', value: '5', source: 'endRange'}, {type: 'literal', value: '/', source: 'endRange'}, {type: 'day', value: '29', source: 'endRange'}, {type: 'literal', value: '/', source: 'endRange'}, {type: 'year', value: '2023', source: 'endRange'}, {type: 'literal', value: ', ', source: 'endRange'}, {type: 'hour', value: '12', source: 'endRange'}, {type: 'literal', value: ':', source: 'endRange'}, {type: 'minute', value: '41', source: 'endRange'}, {type: 'literal', value: ' ', source: 'endRange'}, {type: 'dayPeriod', value: 'PM', source: 'endRange'}]
[ {type: 'month', value: '1', source: 'startRange'}, {type: 'literal', value: '/', source: 'startRange'}, {type: 'day', value: '10', source: 'startRange'}, {type: 'literal', value: '/', source: 'startRange'}, {type: 'year', value: '2018', source: 'startRange'}, {type: 'literal', value: ', ', source: 'startRange'}, {type: 'hour', value: '1', source: 'startRange'}, {type: 'literal', value: ':', source: 'startRange'}, {type: 'minute', value: '00', source: 'startRange'}, {type: 'literal', value: ' ', source: 'startRange'}, {type: 'dayPeriod', value: 'PM', source: 'startRange'}, {type: 'literal', value: ' – ', source: 'shared'}, {type: 'month', value: '5', source: 'endRange'}, {type: 'literal', value: '/', source: 'endRange'}, {type: 'day', value: '29', source: 'endRange'}, {type: 'literal', value: '/', source: 'endRange'}, {type: 'year', value: '2023', source: 'endRange'}, {type: 'literal', value: ', ', source: 'endRange'}, {type: 'hour', value: '12', source: 'endRange'}, {type: 'literal', value: ':', source: 'endRange'}, {type: 'minute', value: '41', source: 'endRange'}, {type: 'literal', value: ' ', source: 'endRange'}, {type: 'dayPeriod', value: 'PM', source: 'endRange'} ]
Преобразование в ISO
СкопированоУ объекта Date
есть метод to
. Он возвращает строку в расширенном ISO-формате — YYYY
. Часовой пояс всегда равен UTC, что обозначено суффиксом Z
.
Intl
не позволяет выбрать в качестве формата iso8601
. Код ниже упадёт с ошибкой:
const date = new Date()const options = { year: 'numeric', month: 'numeric', day: 'numeric'}const isoDate = new Intl.DateTimeFormat( ['iso8601'], options).format(date)// Uncaught RangeError:// Incorrect locale information provided at new DateTimeFormat…
const date = new Date() const options = { year: 'numeric', month: 'numeric', day: 'numeric' } const isoDate = new Intl.DateTimeFormat( ['iso8601'], options).format(date) // Uncaught RangeError: // Incorrect locale information provided at new DateTimeFormat…
Почему возникает такая ошибка?
Дело в том, что Intl
работает только с локалью. Так как в формате ISO-8601 нет никакой локали, то и отформатировать его не получится.
Можно вручную преобразовать дату в формат, совместимый с ISO-8601:
const date = new Date()const dateOptions = { year: 'numeric', month: 'numeric', day: 'numeric',}const formattedDate = new Intl.DateTimeFormat('en-ca', dateOptions).format(date)const timeOptions = { hour: 'numeric', minute: 'numeric', second: 'numeric', hourCycle: 'h24',}const formattedTime = new Intl.DateTimeFormat('en-ca', timeOptions).format(date)const dateTime = `${formattedDate}T${formattedTime}Z`// 2023-05-29T15:00:00Z
const date = new Date() const dateOptions = { year: 'numeric', month: 'numeric', day: 'numeric', } const formattedDate = new Intl.DateTimeFormat('en-ca', dateOptions).format(date) const timeOptions = { hour: 'numeric', minute: 'numeric', second: 'numeric', hourCycle: 'h24', } const formattedTime = new Intl.DateTimeFormat('en-ca', timeOptions).format(date) const dateTime = `${formattedDate}T${formattedTime}Z` // 2023-05-29T15:00:00Z