Кратко
Скопировано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
с текущей датой и временем.
new
создаёт Date
с переданным значением времени. Значение должно быть в формате, который распознается методом Date
, то есть быть совместимым с IETF RFC 2822 или с ISO8601.
new
создаёт класс Date
в местной часовой зоне. Год и месяц являются обязательными параметрами. Остальные параметры, начиная с часов, будут по умолчанию равны 0, а день — 1.
new
создаёт 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.
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.
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 года.
Разбор даты
СкопированоМетод 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
,second
;weekday
,year
,month
,day
;year
,month
,day
;year
,month
;month
,day
;hour
,minute
,second
;hour
,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
поддерживается не всеми древними браузерами.
Вы можете использовать Intl
для форматирования групп дат. В отличие от to
, он позволяет установить формат один раз.
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. Сейчас использовать её не рекомендуется, так как она сильно увеличивает размер собранного приложения. Не добавляйте её в новые проекты.