Для работы с датой и временем в JavaScript используются объекты Date.
Создание
Для создания нового объекта типа Date
используется один из синтаксисов:
new Date()
- Создает объект
Date
с текущей датой и временем:
new Date(milliseconds)
- Создает объект
Date
, значение которого равно количеству миллисекунд (1/1000 секунды), прошедших с 1 января 1970 года GMT+0.
new Date(datestring)
- Если единственный аргумент - строка, используется вызов
Date.parse
для ее разбора. new Date(year, month, date, hours, minutes, seconds, ms)
- Дату можно создать, используя компоненты в местной временной зоне. Для этого формата обязательны только первые два аргумента. Отсутствующие параметры, начиная с
hours
считаются равными нулю, а date
— единице.
Заметим, что год year
должен быть из 4 цифр, а отсчет месяцев month
начинается с нуля 0.Например:
new Date(2011, 0, 1, 0, 0, 0, 0); |
Дата задана с точностью до миллисекунд:
Важность: 5
Дата в местной временной зоне создается при помощи new Date
.
Месяцы начинаются с нуля, так что февраль имеет номер 1. Параметры можно указывать с точностью до минут:
[Открыть задачу в новом окне]
Получение компонентов даты
Для доступа к компонентам даты-времени объекта Date
используются следующие методы:
getFullYear()
- Получить год(из 4 цифр)
getMonth()
- Получить месяц, от 0 до 11.
getDate()
- Получить число месяца, от 1 до 31.
getHours(), getMinutes(), getSeconds(), getMilliseconds()
- Получить соответствующие компоненты.
Некоторые браузеры реализуют нестандартный метод getYear()
. Где-то он возвращает только две цифры из года, где-то четыре. Так или иначе, этот метод отсутствует в стандарте JavaScript. Не используйте его. Для получения года естьgetFullYear()
.
Дополнительно можно получить день недели:
getDay()
- Получить номер дня в неделе. Неделя в JavaScript начинается с воскресенья, так что результат будет числом от 0(воскресенье) до 6(суббота).
Все методы, указанные выше, возвращают результат для местной временной зоны.
Существуют также UTC-варианты этих методов, возвращающие день, месяц, год и т.п. для зоны GMT+0 (UTC): getUTCFullYear()
, getUTCMonth()
, getUTCDay()
. То есть, сразу после "get"
вставляется "UTC"
.
Если ваше локальное время сдвинуто относительно UTC, то следующий код покажет разные часы:
Кроме описанных выше, существуют два специальных метода без UTC-варианта:
getTime()
- Возвращает число миллисекунд, прошедших с 01.01.1970 00:00:00 UTC. Это то же число, которое используется в конструкторе
new Date(milliseconds)
. getTimezoneOffset()
- Возвращает разницу между местным и UTC-временем, в минутах.
Важность: 5
Метод getDay()
позволяет получить номер дня недели, начиная с воскресенья.
Запишем имена дней недели в массив, чтобы можно было их достать по номеру:
[Открыть задачу в новом окне]
Важность: 5
Решение - в использовании встроенной функции getDay
. Она полностью подходит нашим целям, но для воскресенья возвращает 0 вместо 7:
Если удобнее, чтобы день недели начинался с нуля, то можно возвращать в функцииday - 1
, тогда дни будут от 0 (пн) до 6(вс).
[Открыть задачу в новом окне]
Установка компонентов даты
Следующие методы позволяют устанавливать компоненты даты и времени:
setFullYear(year [, month, date])
setMonth(month [, date])
setDate(date)
setHours(hour [, min, sec, ms])
setMinutes(min [, sec, ms])
setSeconds(sec [, ms])
setMilliseconds(ms)
setTime(milliseconds)
(устанавливает всю дату по миллисекундам с 01.01.1970 UTC)
Все они, кроме setTime()
, обладают также UTC-вариантом, например: setUTCHours()
.
Как видно, некоторые методы могут устанавливать несколько компонентов даты одновременно, в частности, setHours
. При этом если какая-то компонента не указана, она не меняется. Например:
Автоисправление даты
Автоисправление — очень удобное свойство объектов Date
. Оно заключается в том, что можно устанавливать заведомо некорректные компоненты (например 32 января), а объект сам себя поправит.
Неправильные компоненты даты автоматически распределяются по остальным.
Например, нужно увеличить на 2 дня дату «28 февраля 2011». Может быть так, что это будет 2 марта, а может быть и 1 марта, если год високосный. Но нам обо всем этом думать не нужно. Просто прибавляем два дня. Остальное сделает Date
:
Также это используют для получения даты, отдаленной от имеющейся на нужный промежуток времени. Например, получим дату на 70 секунд большую текущей:
Можно установить и нулевые, и даже отрицательные компоненты. Например:
Важность: 4
Создадим текущую дату и вычтем 100 дней:
Объект Date
авто-исправит себя и выдаст правильный результат.
Обратите внимание на массив с именами дней недели. «Нулевой» день — воскресенье.
[Открыть задачу в новом окне]
Важность: 5
Создадим дату из следующего месяца, но день не первый, а «нулевой» (т.е. предыдущий):
[Открыть задачу в новом окне]
Преобразование к числу, разность дат
Когда объект Date
используется в числовом контексте, он преобразуется в количество миллисекунд:
Важный побочный эффект: даты можно вычитать, результат вычитания объектов Date
— их временная разница, в миллисекундах.
Это используют для измерения времени:
Важность: 5
Первая часть.
Для вывода достаточно сгенерировать date
, соответствующий началу дня, т.е. «сегодня» 00 часов 00 минут 00 секунд.
Разница между текущей датой и началом дня — это количество миллисекунд от начала дня. Его можно легко перевести в секунды:
Вторая часть
Для получения оставшихся до конца дня секунд нужно из «завтра 00ч 00мин 00сек» вычесть текущее время.
Чтобы сгенерировать «завтра», нужно увеличить текущий день на 1:
[Открыть задачу в новом окне]
Бенчмаркинг
Допустим, у нас есть несколько вариантов решения задачи, каждый описан функцией.
Как узнать, какой быстрее?
Для примера возьмем две функции, которые округляют число:
1 |
function floorMath(x) { |
Чтобы померять, какая из них быстрее, нельзя запустить один раз floorMath
, один раз floorXor
и замерить разницу. Одноразовый запуск ненадежен, любая мини-помеха исказит результат.
Для правильного бенчмаркинга функция запускается много раз, чтобы сам тест занял существенное время. Это сведет влияние помех к минимуму. Сложную функцию можно запускать 100 раз, простую — 1000 раз…
Померяем, какая из функций округления быстрее:
В зависимости от браузера, может быть быстрее как floorXor
так и floorMath
.
Представим себе — во время первого бенчмаркинга bench(floorMath)
компьютер что-то делал параллельно важное (вдруг) и это занимало ресурсы, а во время второго — перестал. Реальная ситуация? Конечно реальна, особенно на современных ОС.
Гораздо более надежные результаты можно получить, весь пакет тестов прогнать много раз.
Форматирование
Встроенные в Date
методы форматирования используются редко, и преимущественно, для отладки.
toString()
, toDateString()
, toTimeString()
- Возвращают стандартное строчное представление, не указанное в стандарте, а зависящее от браузера. Единственное требование - читаемость человеком. Метод
toString
возвращает дату целиком, toDateString()
и toTimeString()
- только дату и время соответственно.
toLocaleString()
, toLocaleDateString()
, toLocaleTimeString()
- То же самое, но строка должна быть с учетом локальных настроек и языка посетителя.
toUTCString()
- То же самое, что
toString()
, но дата в зоне UTC. toISOString()
- Возвращает дату в формате ISO Детали формата будут далее. Поддерживается современными браузерами, не поддерживается IE<9.
Встроенные методы форматирования Date
не допускают указание собственного формата.
Поэтому, как правило, любой вывод, кроме отладочного, форматируется своей, а не встроенной функцией.
Важность: 3
Получим компоненты один за другим.
- День можно получить как
date.getDate()
. При необходимости добавим ведущий ноль:
date.getMonth()
возвратит месяц, начиная с нуля. Увеличим его на 1:
var mm = date.getMonth() + 1; |
date.getFullYear()
вернет год в 4-значном формате. Чтобы сделать его двузначным - воспользуемся оператором взятия остатка '%'
:
var yy = date.getFullYear() % 100; |
Заметим, что год, как и другие компоненты, может понадобиться дополнить нулем слева, причем возможно что yy == 0
(например, 2000 год). При сложении со строкой 0+'0' == '00'
, так что будет все в порядке.
Полный код:
[Открыть задачу в новом окне]
Важность: 4
Для того, чтобы узнать время от date
до текущего момента - используем вычитание дат.
[Открыть задачу в новом окне]
Разбор строки, Date.parse
Все современные браузеры, включая IE9+, понимают даты в упрощенном формате ISO 8601 Extended.
Этот формат выглядит так: YYYY-MM-DDTHH:mm:ss.sssZ
. Для разделения даты и времени в нем используется символ 'T'
. Часть 'Z'
обозначает (необязательную) временную зону — она может отсутствовать, тогда зона UTC, либо может быть символ z
— тоже UTC, или зона в формате +-hh:mm
.
Также возможны упрощенные варианты, к примеру:
Метод
Date.parse(str)
разбирает строку
str
в таком формате и возвращает соответствующее ей количество миллисекунд. Если это невозможно,
Date.parse
возвращает
NaN
.
На момент написания некоторые браузеры (Safari) воспринимали формат без 'Z'
как дату в локальной таймзоне (по стандарту UTC), поэтому пример ниже в них работает некорректно:
С таймзоной -07:00 GMT
в конце все современные браузеры работают правильно:
До появления спецификации EcmaScript 5 формат не был стандартизован, и браузеры, включая IE8-, имели свои собственные форматы дат. Частично, эти форматы пересекаются.
Например, код ниже работает везде, включая старые IE:
Вы также можете почитать о старых форматах IE в документации к методу MSDN Date.parse.
Конечно же, сейчас лучше использовать современный формат, если цель — современные браузеры, а если дополнительно нужны IE8-, то либо передавать даты через миллисекунды, а не строки, либо добавить библиотеку типа es5-shim, которая добавит Date.parse
в старые IE.
Итого
- Дата и время представлены в JavaScript одним объектом: Date. Создать «только время» при этом нельзя, оно должно быть с датой. Список методов
Date
вы можете найти в справочникеDate или выше.
- Объект
Date
удобен тем, что автокорректируется. Благодаря этому легко сдвигать даты.
- Объекты
Date
можно вычитать, результатом будет разница в мс.
Комментарии
Оставить комментарий
Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)
Термины: Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)