Работа с датами в javascript может быть
непростой. В данной статье мы рассмотрим принципы работы с ними.
Введение
Работа с
датами может быть очень сложной. Вне
зависимости от используемой технологии.
JavaScript предоставляет
функциональность по работе с датами через объект
Date.
Данная
статься не рассматривает библиотеку Moment.js которая ялвяется самой лучшей библиотекой по
работе с датами, и вы всегда можете ей пользоваться.
Объект Date
Экземпляр
объекта Date представляет точку
времени.
Несмотря
на название
Date, объект
также обрабатывает и время.
Инициализация объекта Date
Ниже
показано как мы инициализируем объект Date.
newDate()
Этот код
создает объект Date который
указывает на текущий момент времени.
Внутри
объекта информация о времени хранится в милисекундах от 1го января 1970 года (UTC). Эта дата используется как время начало компьютерной
эры.
Вам может
быть знаком штамп времени UNIX: он представляет собой число секунд от известной даты.
Важно:
обратите внимание что штамп времен UNIX в секундах, а время в JavaScript в
милисекундах.
Если у
нас есть время UNIX, то следующим образом мы можем создать объект Date:
consttimestamp=1530826365
newDate(timestamp*1000)
Если мы
передадим 0 при создании объекта, то получим дату 1 января 1970 года (UTC).
newDate(0)
Если мы
передадим не число а строку, то объект будет использовать метода
parse для определения даты, котору необходимо присвоить
объекту.
Например:
newDate('2018-07-22')
newDate('2018-07')//July 1st 2018, 00:00:00
newDate('2018')//Jan 1st 2018, 00:00:00
newDate('07/22/2018')
newDate('2018/07/22')
newDate('2018/7/22')
newDate('July 22, 2018')
newDate('July 22, 2018 07:22:13')
newDate('2018-07-22 07:22:13')
newDate('2018-07-22T07:22:13')
newDate('25 March 2018')
newDate('25 Mar 2018')
newDate('25 March, 2018')
newDate('March 25, 2018')
newDate('March 25 2018')
newDate('March 2018')//Mar 1st 2018, 00:00:00
newDate('2018 March')//Mar 1st 2018, 00:00:00
newDate('2018 MARCH')//Mar 1st 2018, 00:00:00
newDate('2018 march')//Mar 1st 2018, 00:00:00
Здесь все
достаточно гибко. Вы можете добавлять или убирать дополнительные нули в месяцы
и дни.
Будте внимательны с позицией месяца/дня,
иначе вы можете их перепутать и получить совсем не то что ожидали.
Также вы
можете использовать метод
Date.parse:Date.parse('2018-07-22')
Date.parse('2018-07')//July 1st 2018, 00:00:00
Date.parse('2018')//Jan 1st 2018, 00:00:00
Date.parse('07/22/2018')
Date.parse('2018/07/22')
Date.parse('2018/7/22')
Date.parse('July 22, 2018')
Date.parse('July 22, 2018 07:22:13')
Date.parse('2018-07-22 07:22:13')
Date.parse('2018-07-22T07:22:13')
Этот
объект вернет вам штамп времени в милисекундах а не объект Date.
Вы также
можете передать набор упорядоченных значений который представляют части даты:
год, месяц (начиная с 0), день, час, минуты, секунды и милисекунды.
newDate(2018,6,22,7,22,13,0)
newDate(2018,6,22)
Как
минимум вы должны предоставить три параметра, но многие интерпретаторы
позволяют и меньшее число параметров:
newDate(2018,6)//Sun Jul 01 2018 00:00:00 GMT+0200 (Central European Summer Time)
newDate(2018)//Thu Jan 01 1970 01:00:02 GMT+0100 (Central European Standard Time)
В каждом
из этих случаев, в результате будет дата указанная относительно вашей временной
зоны. Это значит что результат на двух
компьютерах может отличаться результат работы с одним и тем же объектом.
JavaScript без
предоставления ему какой либо информации о временных зоназ будет считать, что
время в UTC, и будет автоматически переводить его в локальное время.
Таким
образом, вы можете создать новый объект Date четырмя способами:
- Не передавая никаких параметров, в этом случае объект Date будет представлять текущее врмя.
- Передавая число, которое представляет собой число милисекунд с 1 января 1970
года.
- Передавая строку, которая описывает дату.
- Передавая набор параметров, которые представляют информацию о различных
частях даты.
Временные зоны
Когда мы
инициализируем дату вы можете передать временную зону, такоим образом объект Date не будет предполагать
что это UTC дата и не будет
осуществлять перевод к вашей временной зоне.
Вы можете
передать временную зону в +HOURS формате, или передавая название зоны в скобках:
newDate('July 22, 2018 07:22:13 +0700')
newDate('July 22, 2018 07:22:13 (CET)')
Если вы
укажете временную зону неправильно в скобках, JavaScript без предупреждений будет эту дату трактовать как UTC.
Если вы
укажете неправильно числовой формат, JavaScript будет
полагать что это неправильная дата.
Преобразование и форматирование даты
Если есть
объект Date, то для него существует много способов преобразования в
строку:
constdate=newDate('July 22, 2018 07:22:13')
date.toString()// "Sun Jul 22 2018 07:22:13 GMT+0200 (Central European Summer Time)"
date.toTimeString()//"07:22:13 GMT+0200 (Central European Summer Time)"
date.toUTCString()//"Sun, 22 Jul 2018 05:22:13 GMT"
date.toDateString()//"Sun Jul 22 2018"
date.toISOString()//"2018-07-22T05:22:13.000Z" (ISO 8601 format)
date.toLocaleString()//"22/07/2018, 07:22:13"
date.toLocaleTimeString()//"07:22:13"
date.getTime()//1532236933000
Методы получения объекта Date
Объект Date предоставляет
несколько методов для проверки значения. Все они зависят от текущей временной
зоны компьютера:
constdate=newDate('July 22, 2018 07:22:13')
date.getDate()//22
date.getDay()//0 (0 means sunday, 1 means monday..)
date.getFullYear()//2018
date.getMonth()//6 (starts from 0)
date.getHours()//7
date.getMinutes()//22
date.getSeconds()//13
date.getMilliseconds()//0 (not specified)
date.getTime()//1532236933000
date.getTimezoneOffset()//-120 (will vary depending on where you are and when you check - this is CET during the summer). Returns the timezone difference expressed in minutes
Вот
эквивалентные методы для UTC, они возвращают UTC значение а не
значение для вашей зоны:
date.getUTCDate()//22
date.getUTCDay()//0 (0 means sunday, 1 means monday..)
date.getUTCFullYear()//2018
date.getUTCMonth()//6 (starts from 0)
date.getUTCHours()//5 (not 7 like above)
date.getUTCMinutes()//22
date.getUTCSeconds()//13
date.getUTCMilliseconds()//0 (not specified)
Редактирование даты
Объект Date предоставляет
несколько методов для редактирования значения:
constdate=newDate('July 22, 2018 07:22:13')
date.setDate(newValue)
date.setDay(newValue)
date.setFullYear(newValue)//note: avoid setYear(), it's deprecated
date.setMonth(newValue)
date.setHours(newValue)
date.setMinutes(newValue)
date.setSeconds(newValue)
date.setMilliseconds(newValue)
date.setTime(newValue)
date.setTimezoneOffset(newValue)
setDay и setMonth начинают отсчет с 0, то есть скажем март –
это номер 2.
Интересный
факт: эти методы «перекрывающие», то есть если вы введете например
date.setHours(48), то это метод увеличит и день.
Полезно
знать: в можете передать больше чем один параметр в
setHours() для того что бы
указать минуты, секунды и милисекунды. setHours(0, 0, 0, 0) – то же самое
касается и setMinutes и setSeconds.
Как и для
getXXX, эти методы имеют UTC эквиваленты:
constdate=newDate('July 22, 2018 07:22:13')
date.setUTCDate(newalue)
date.setUTCDay(newValue)
date.setUTCFullYear(newValue)
date.setUTCMonth(newValue)
date.setUTCHours(newValue)
date.setUTCMinutes(newValue)
date.setUTCSeconds(newValue)
date.setUTCMilliseconds(newValue)
Получение текущего штампа вермени
Если вы
хотите получить текущий штамп времени в милисекундах, вы можете использовать
сокращение вида:
Date.now()
вместо
newDate().getTime()
JavaScript старается работать хорошо
Обратите
внимание. Если вы переполните месяц числом дней, то это не приведет
к ошибке, и в дате просто сменится месяц:
newDate(2018,6,40)//Thu Aug 09 2018 00:00:00 GMT+0200 (Central European Summer Time)
То же
самое касается месяцев, часов, минут, секунд или милисекунд.
Форматирование даты в локальном формате
API интернационализации,
которое хорошо
поддерживается в нынешних браузерах (за исключением UC Browser), позволяют вам преобразовывать дату.
Это
достигается с помощью объекта
Intl, которые также помогает в локализации чисел, строк и
валют.
Нам же
инетерсна в первую очередь функция
Intl.DateTimeFormat().
Ниже
показан пример ее использования.
Форматирование
даты в соответствии с текущей локалью компьютера:
// "12/22/2017"
constdate=newDate('July 22, 2018 07:22:13')
newIntl.DateTimeFormat().format(date)//"22/07/2018" in my locale
Форматирование
даты для другой локали:
newIntl.DateTimeFormat('en-US').format(date)//"7/22/2018"
Метод
Intl.DateTimeFormat принимает опциональный параметр, который позволяет
кастомизировать результат. Для того что бы отобразить часы, минуты и секунды: constoptions={
year:'numeric',
month:'numeric',
day:'numeric',
hour:'numeric',
minute:'numeric',
second:'numeric'
}
newIntl.DateTimeFormat('en-US',options).format(date)//"7/22/2018, 7:22:13 AM"
newIntl.DateTimeFormat('it-IT',options2).format(date)//"22/7/2018, 07:22:13"
Здесь
представлены все параметры которые можно использовать.
Сравнение двух дат
Вы можете
вычислить разницу между двумя датами используя метод
Date.getTime():constdate1=newDate('July 10, 2018 07:22:13')
constdate2=newDate('July 22, 2018 07:22:13')
constdiff=date2.getTime()-date1.getTime()//difference in milliseconds
Подобным
образом вы можете проверить равны ли две даты:
constdate1=newDate('July 10, 2018 07:22:13')
constdate2=newDate('July 10, 2018 07:22:13')
if(date2.getTime()===date1.getTime()){
//dates are equal
}
Имейте
ввиду, что метод
getTime() возвращает количество милисекунд, таким образом вам нужно
учитывать время в сравнении. July 10, 2018 07:22:13 не равен
July 10, 2018. В данном случае вы
можете использовать setHours(0, 0, 0, 0) для сброса времени.