Для работы с датой и временем в 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)