Кратко
СкопированоDate — класс для работы со временем. В основном используется для отображения и вычисления.
Время отображается в двух форматах:
- UTC — время по Гринвичу;
- В текущей часовой зоне (например, UTC+3 для Москвы).
Поэтому часть методов для взаимодействия со временем имеют два формата — для UTC и для текущей часовой зоны.
Как понять
СкопированоКласс Date используется для отображения даты в различных форматах. Там, где нужно находить разницу между датами, Date тоже прекрасно справится.
Пример
СкопированоСоздадим новый экземпляр даты:
const currentDate = new Date('August 14, 2022 14:15:30')
const currentDate = new Date('August 14, 2022 14:15:30')
Получаем различные части даты:
console.log(currentDate.getDay())// 0console.log(currentDate.getHours())// 14console.log(currentDate.getTime())// 1660475730000console.log(currentDate.getFullYear())// 2022console.log(currentDate.toISOString())// 2022-08-14T11:15:30.000Z
console.log(currentDate.getDay())
// 0
console.log(currentDate.getHours())
// 14
console.log(currentDate.getTime())
// 1660475730000
console.log(currentDate.getFullYear())
// 2022
console.log(currentDate.toISOString())
// 2022-08-14T11:15:30.000Z
Установим новую дату:
currentDate.setMonth(0, 1)console.log(currentDate.toLocaleDateString())// 01.01.2022
currentDate.setMonth(0, 1)
console.log(currentDate.toLocaleDateString())
// 01.01.2022
Также можно создавать дату в формате UTC:
const utcDate = new Date(Date.UTC(2022, 8, 14, 14, 15, 30))console.log(utcDate.toISOString())// 2022-09-14T14:15:30.000Z
const utcDate = new Date(Date.UTC(2022, 8, 14, 14, 15, 30))
console.log(utcDate.toISOString())
// 2022-09-14T14:15:30.000Z
Как пишется
СкопированоDate может немного запутать, часть параметров начинают отсчёт с нуля, а часть с 1.
Например, при установке месяца, отсчёт идёт с 0, где 0 — это январь. При выводе дня недели возвращаемое значение также начинается с 0 и означает воскресенье.
Исключением из этого правила являются параметры, связанные с годом и днём месяца (первое число месяца — 1).
Основные методы
СкопированоСоздание
СкопированоСоздать новый экземпляр класса можно несколькими способами:
-
newсоздаёт экземплярDate ( ) Dateс текущей датой и временем. -
newсоздаётDate ( значение ) Dateс переданным значением времени. Значение должно быть в формате, который распознается методомDate, то есть быть совместимым с IETF RFC 2822 или с ISO8601.. parse ( ) -
newсоздаёт классDate ( год , месяц , день , часы , минуты , секунды , миллисекунды ) Dateв местной часовой зоне. Год и месяц являются обязательными параметрами. Остальные параметры, начиная с часов, будут по умолчанию равны 0, а день — 1. -
newсоздаётDate ( миллисекунды ) Dateсо временем в миллисекундах. Количество миллисекунд измеряется с 1 января 1970 года UTC.
const millisecondsDate = new Date(120000)console.log(millisecondsDate.toISOString())// 1970-01-01T00:02:00.000Z
const millisecondsDate = new Date(120000)
console.log(millisecondsDate.toISOString())
// 1970-01-01T00:02:00.000Z
Получение значений
Скопированоget— возвращает год;Full Year ( ) get— возвращает месяц с 0 до 11;Month ( ) get— возвращает день месяца с 1 до 31;Date ( ) get— возвращает порядковый номер дня недели с 0 до 6;Day ( ) get— возвращает часы с 0 до 23;Hours ( ) get- возвращает минуты от 0 до 59;Minutes ( ) get- возвращает секунды от 0 до 59;Seconds ( ) get- возвращает миллисекунды от 0 до 999.Milliseconds ( )
Все вышеперечисленные методы возвращают значения для текущей часовой зоны. Если необходимо вернуть время по Гринвичу, то нужно в метод добавить UTC: get, get, get, get, get, get,
get, get.
Есть два метода, которые не привязаны к часовой зоне:
getвозвращает значение в миллисекундах, прошедших с 1 января 1970 года, соответствующее указанной дате по UTC.Time ( )
const currentDate = new Date(2022, 11)console.log(currentDate.toISOString())// 2022-11-30T21:00:00.000Zconsole.log(currentDate.getTime())// 1672520400000
const currentDate = new Date(2022, 11)
console.log(currentDate.toISOString())
// 2022-11-30T21:00:00.000Z
console.log(currentDate.getTime())
// 1672520400000
getвозвращает смещение в минутах между текущей часовой зоной и UTC.Timezone Offset ( )
const currentDate = new Date()console.log(currentDate.getTimezoneOffset())// -180
const currentDate = new Date()
console.log(currentDate.getTimezoneOffset())
// -180
Установка значений
СкопированоТакже, как и с получением значений, у многих методов есть присваивание значений в локальной часовой зоне и UTC. Для локальной:
setустанавливает год, значения месяца и дня необязательны.Full Year ( год , месяц , день ) setустанавливает месяц, передавать день необязательно.Month ( месяц , день ) setустанавливает день месяца.Date ( день ) setустанавливает часы. Значения минут, секунд, миллисекунд необязательны.Hours ( часы , минуты , секунды , миллисекунды ) set- устанавливает минуты. Секунды и миллисекунды необязательны.Minutes ( минуты , секунды , миллисекунды ) setустанавливает секунды. Миллисекунды передавать необязательно.Seconds ( секунды , миллисекунды ) set- устанавливает миллисекунды.Milliseconds ( миллисекунды )
Для UTC аналогичные методы, только добавляем UTC после set. Например, set.
И метод, который относится только к UTC:
setустанавливает значение, которое равно количеству миллисекунд, прошедших с 1 января 1970 года.Time ( значение )
Разбор даты
СкопированоМетод Date используется для разбора (ещё говорят парсинга) строкового представления даты. Возвращает значение, равное количеству миллисекунд, прошедших с 1 января 1970 года.
Переданное значение должно быть совместимым с IETF RFC 2822 или с ISO8601.
console.log(Date.parse('2022-11-30T21:00:00.000Z'))// 1669842000000
console.log(Date.parse('2022-11-30T21:00:00.000Z'))
// 1669842000000
Форматирование даты
СкопированоДля отображения Date в различных форматах существует метод to.
Локаль — это необязательный параметр, который является строкой или массивом строк с языковой меткой BCP 47. Например, en или de. Локаль хранит региональные настройки о формате дат, номеров, адресов.
Опции — необязательный параметр с объектом настроек. Доступные свойства:
-
locale— алгоритм поиска локали, используется для выбора подходящей локали. Принимает значенияMatcher lookupилиbest fit. По умолчаниюbest fit. -
time— значение используемого часовой зоны. Все браузеры должны принимать значениеZone UTC, значение по умолчанию равно значению часовой зоны среды выполнения. Формат принимаемого значения может различаться в различных браузерах. -
hour12— значение, которое определяет, использовать ли 12-часовой формат вывода. Принимаетtrueилиfalse. -
format— алгоритм поиска формата, используется для выбора формата отображения. Принимает значенияMatcher basicилиbest fit. По умолчаниюbest fit. -
time— формат названия часовой зоны. ПринимаетZone Name longилиshort. -
weekday— значение дня недели. Принимаетnarrow,shortиlong. -
era— значение эры. Принимаетnarrow,shortиlong. -
year— значение года. Принимаетnumericи2.- digit -
month— значения месяца. Принимаетnumeric,2,- digit narrow,shortиlong. -
day— значения дня. Принимаетnumericи2.- digit -
hour— значения часа. Принимаетnumericи2.- digit -
minute— значения минут. Принимаетnumericи2.- digit -
second— значения секунд. Принимаетnumericи2.- digit
Браузеры обязаны поддерживать следующие наборы настроек отображения:
weekday,year,month,day,hour,minute,secondweekday,year,month,dayyear,month,dayyear,monthmonth,dayhour,minute,secondhour,minute
Некоторые браузеры могут поддерживать форматы вывода сверх этих наборов, но данный момент необходимо уточнять в спецификации браузеров.
Отобразим в двух форматах:
const currentDate = new Date('August 14, 2022 14:15:30')const options = { hour: 'numeric', minute: 'numeric', second: 'numeric', timeZoneName: 'long'}console.log(currentDate.toLocaleDateString('ru-RU', options))// 14.08.2022, 14:15:30 Москва, стандартное времяconsole.log(currentDate.toLocaleDateString('en-US', options))// 8/14/2022, 2:15:30 PM Moscow Standard Time
const currentDate = new Date('August 14, 2022 14:15:30')
const options = {
hour: 'numeric', minute: 'numeric', second: 'numeric',
timeZoneName: 'long'
}
console.log(currentDate.toLocaleDateString('ru-RU', options))
// 14.08.2022, 14:15:30 Москва, стандартное время
console.log(currentDate.toLocaleDateString('en-US', options))
// 8/14/2022, 2:15:30 PM Moscow Standard Time
Получение текущего времени
СкопированоDate — метод, который возвращает текущее время в миллисекундах, прошедших с 1 января 1970 года UTC.
Метод очень похож на new , но, так как нет ключевого слова new, экземпляр класса не создаётся, возвращается только число:
console.log(Date.now())// 1661370397669
console.log(Date.now())
// 1661370397669
Математические операции
СкопированоНайдём количество дней между 1 января 2022 и 31 декабря 2022.
Полученное значение = количество дней в году - 1.
const utcDateOne = new Date(Date.UTC(2022, 0, 1, 0, 0, 0))const utcDateTwo = new Date(Date.UTC(2022, 11, 31, 0, 0, 0))console.log(utcDateOne.toUTCString())// Sat, 01 Jan 2022 00:00:00 GMTconsole.log(utcDateTwo.toUTCString())// Sat, 31 Dec 2022 00:00:00 GMTconst result = utcDateTwo - utcDateOneconsole.log(result)// 31449600000 миллисекундconsole.log(result / (1000 * 60 * 60 * 24))// 364
const utcDateOne = new Date(Date.UTC(2022, 0, 1, 0, 0, 0))
const utcDateTwo = new Date(Date.UTC(2022, 11, 31, 0, 0, 0))
console.log(utcDateOne.toUTCString())
// Sat, 01 Jan 2022 00:00:00 GMT
console.log(utcDateTwo.toUTCString())
// Sat, 31 Dec 2022 00:00:00 GMT
const result = utcDateTwo - utcDateOne
console.log(result)
// 31449600000 миллисекунд
console.log(result / (1000 * 60 * 60 * 24))
// 364
Автокоррекция даты
СкопированоDate имеет интересное свойство: этот класс автоматически исправляет некорректно введённые значения. Например, при попытке установки 32 декабря, Date прибавит 1 день к максимальному корректному значению (31 декабря) и установит корректную дату.
const newDate = new Date()newDate.setFullYear(2022, 11, 32)console.log(newDate.toISOString())// 2023-01-01T14:41:49.635Z
const newDate = new Date()
newDate.setFullYear(2022, 11, 32)
console.log(newDate.toISOString())
// 2023-01-01T14:41:49.635Z
С минусом тоже сработает. Только Date будет вычитать значение:
const newDate = new Date()newDate.setFullYear(1996, -11, 24)console.log(newDate.toISOString())// 1995-02-24T05:17:21.204Z
const newDate = new Date()
newDate.setFullYear(1996, -11, 24)
console.log(newDate.toISOString())
// 1995-02-24T05:17:21.204Z
Также можно установить нулевое значение там, где Date возвращает ненулевые значения. Например, для дня месяца. Тогда класс просто вычтет 1 день.
const newDate = new Date('August 14, 2022 14:15:30')newDate.setDate(0)console.log(newDate.toISOString())// 2022-07-31T11:15:30.000Z
const newDate = new Date('August 14, 2022 14:15:30')
newDate.setDate(0)
console.log(newDate.toISOString())
// 2022-07-31T11:15:30.000Z
// Обе переменных представляют одну и ту же датуconst dateOne = new Date(Date.UTC(2022, 11, 31, 0, 0, 0))const dateTwo = new Date(Date.UTC(2022, 12, 0, 0, 0, 0))console.log(dateOne.toISOString())console.log(dateTwo.toISOString())// 2022-12-31T00:00:00.000Z// 2022-12-31T00:00:00.000Z
// Обе переменных представляют одну и ту же дату
const dateOne = new Date(Date.UTC(2022, 11, 31, 0, 0, 0))
const dateTwo = new Date(Date.UTC(2022, 12, 0, 0, 0, 0))
console.log(dateOne.toISOString())
console.log(dateTwo.toISOString())
// 2022-12-31T00:00:00.000Z
// 2022-12-31T00:00:00.000Z
Альтернативы
СкопированоВместо использования to можно использовать класс Intl.
const currentDate = new Date('August 14, 2022 14:15:30')const options = { year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric', timeZoneName: 'long'}console.log(new Intl.DateTimeFormat('ru-RU', options).format(currentDate))// 14.08.2022, 14:15:30 Москва, стандартное времяconsole.log(new Intl.DateTimeFormat('en-US', options).format(currentDate))// 8/14/2022, 2:15:30 PM Moscow Standard Time
const currentDate = new Date('August 14, 2022 14:15:30')
const options = {
year: 'numeric', month: 'numeric', day: 'numeric',
hour: 'numeric', minute: 'numeric', second: 'numeric',
timeZoneName: 'long'
}
console.log(new Intl.DateTimeFormat('ru-RU', options).format(currentDate))
// 14.08.2022, 14:15:30 Москва, стандартное время
console.log(new Intl.DateTimeFormat('en-US', options).format(currentDate))
// 8/14/2022, 2:15:30 PM Moscow Standard Time
На практике
Скопированосоветует
Скопировано🛠 Intl и to реализовывают похожую функциональность, но есть небольшая разница в использовании.
Их реализация в браузерах также может отличаться, так как нет строгой спецификации и каждый браузер может интерпретировать требования по-разному. Поэтому нет универсального решения, что именно использовать.
Основные отличия:
-
В поддержке браузеров.
Intlподдерживается не всеми древними браузерами.. DateTime Format -
Вы можете использовать
Intlдля форматирования групп дат. В отличие от. DateTime Format to, он позволяет установить формат один раз.Locale Date String ( )
const dateOne = new Date('August 14, 2022 14:15:30')const dateTwo = new Date('December 26, 1991 02:00:30')const options = { year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric', timeZoneName: 'long', timeZone: 'UTC'}const formatter = new Intl.DateTimeFormat('ru-RU', options)console.log(formatter.format(dateOne))// 14.08.2022, 11:15:30 Всемирное координированное времяconsole.log(formatter.format(dateTwo))// 26.12.1991, 0:00:30 Всемирное координированное время
const dateOne = new Date('August 14, 2022 14:15:30')
const dateTwo = new Date('December 26, 1991 02:00:30')
const options = {
year: 'numeric', month: 'numeric', day: 'numeric',
hour: 'numeric', minute: 'numeric', second: 'numeric',
timeZoneName: 'long',
timeZone: 'UTC'
}
const formatter = new Intl.DateTimeFormat('ru-RU', options)
console.log(formatter.format(dateOne))
// 14.08.2022, 11:15:30 Всемирное координированное время
console.log(formatter.format(dateTwo))
// 26.12.1991, 0:00:30 Всемирное координированное время
- Различный ввод/вывод. Так как стандарт не является строгим, то передаваемые параметры могут отличаться. Особенно это касается часовых зон. Значения вывода по умолчанию также могут отличаться.
const date = new Date(1660475730000)console.log(date.toLocaleString('en-US'))// 8/14/2022, 2:15:30 PMconsole.log(new Intl.DateTimeFormat('en-US').format(date))// 8/14/2022
const date = new Date(1660475730000)
console.log(date.toLocaleString('en-US'))
// 8/14/2022, 2:15:30 PM
console.log(new Intl.DateTimeFormat('en-US').format(date))
// 8/14/2022
Поэтому, если вам не так критично поддерживать браузеры, с маленьким процентом использования клиентами, то я советую использовать Intl.
🛠 Если вам не хватает функциональности, представленной классом Date, например, недостаточно его возможностей форматирования или парсинга, то можно посмотреть в сторону библиотек day.js или date-fns.
❌ Раньше золотым стандартом была библиотека moment.js. Сейчас использовать её не рекомендуется, так как она сильно увеличивает размер собранного приложения. Не добавляйте её в новые проекты.