Вам бонус- начислено 1 монета за дневную активность. Сейчас у вас 1 монета

Дата и Время в JS

Лекция



Привет, сегодня поговорим про дата в JS, обещаю рассказать все что знаю. Для того чтобы лучше понимать что такое дата в JS, время в JS , настоятельно рекомендую прочитать все из категории Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend).


  1. Создание
  2. Получение компонентов даты
  3. Установка компонентов даты
    1. Автоисправление даты
    2. Преобразование к числу, разность дат
    3. Бенчмаркинг
  4. Форматирование
    1. Разбор строки, Date.parse
  5. Итого

Для работы с датой и временем в JavaScript используются объекты Date.

Создание

Для создания нового объекта типа Date используется один из синтаксисов:

new Date()
Создает объект Date с текущей датой и временем:
   
1 var now = new Date();
2 alert(now);
new Date(milliseconds)
Создает объект Date, значение которого равно количеству миллисекунд (1/1000 секунды), прошедших с 1 января 1970 года GMT+0.
   
1 // 24 часа после 01.01.1970 GMT+0
2 var Jan02_1970 = new Date(3600*24*1000);
3 alert( Jan02_1970 );
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) // 1 января 2011, 00:00:00 в местной временной зоне
new Date(2011, 0) // то же самое, date по умолчанию равно 1
new Date(2011, 0, 1, 0, 0, 0, 0); // то же самое

 

Дата задана с точностью до миллисекунд:

 

   
1 var d = new Date(2011, 0, 1, 2, 3, 4, 567);
2 alert(d); // 1.01.2011, 02:03:04.567

 

 

Важность: 5

Создайте объект Date для даты: 20 февраля 2012 года, 3 часа 12 минут.

Временная зона — местная. Выведите его на экран.

Решение

Дата в местной временной зоне создается при помощи new Date.

Месяцы начинаются с нуля, так что февраль имеет номер 1. Параметры можно указывать с точностью до минут:

 

   
1 var d = new Date(2012, 1, 20, 3, 12);
2 alert(d);

 

[Открыть задачу в новом окне]

 

Получение компонентов даты

Для доступа к компонентам даты-времени объекта Date используются следующие методы:

getFullYear()
Получить год(из 4 цифр)
getMonth()
Получить месяц, от 0 до 11.
getDate()
Получить число месяца, от 1 до 31.
getHours(), getMinutes(), getSeconds(), getMilliseconds()
Получить соответствующие компоненты.

 

Устаревший getYear()

Некоторые браузеры реализуют нестандартный метод getYear(). Где-то он возвращает только две цифры из года, где-то четыре. Так или иначе, этот метод отсутствует в стандарте JavaScript. Не используйте его. Для получения года естьgetFullYear().

 

Дополнительно можно получить день недели:

getDay()
Получить номер дня в неделе. Неделя в JavaScript начинается с воскресенья, так что результат будет числом от 0(воскресенье) до 6(суббота).

Все методы, указанные выше, возвращают результат для местной временной зоны.

Существуют также UTC-варианты этих методов, возвращающие день, месяц, год и т.п. для зоны GMT+0 (UTC): getUTCFullYear()getUTCMonth()getUTCDay(). То есть, сразу после "get"вставляется "UTC".

Если ваше локальное время сдвинуто относительно UTC, то следующий код покажет разные часы:

   
1 var date = new Date();
2  
3 alert( date.getHours() ); // час в вашей зоне для даты date
4 alert( date.getUTCHours() ); // час в зоне GMT+0 для даты date

 

Кроме описанных выше, существуют два специальных метода без UTC-варианта:

getTime()
Возвращает число миллисекунд, прошедших с 01.01.1970 00:00:00 UTC. Это то же число, которое используется в конструкторе new Date(milliseconds).
getTimezoneOffset()
Возвращает разницу между местным и UTC-временем, в минутах.

 

   
1 alert( new Date().getTimezoneOffset() );  // Для GMT-1 выведет 60

 

 

Важность: 5

Создайте функцию getWeekDay(date), которая выводит текущий день недели в коротком формате ‘пн’, ‘вт’, … ‘вс’.

Например:

var date = new Date(2012,0,3);  // 3 января 2012
alert( getWeekDay(date) );      // Должно вывести 'вт'

 

Решение

Метод getDay() позволяет получить номер дня недели, начиная с воскресенья.

Запишем имена дней недели в массив, чтобы можно было их достать по номеру:

 

   
1 function getWeekDay(date) {
2   var days = ['вс','пн','вт','ср','чт','пт','сб'] ;
3  
4   return days[ date.getDay() ];
5 }
6  
7 var date = new Date(2012,0,3);  // 3 января 2012
8 alert( getWeekDay(date) );      // 'вт'

 

[Открыть задачу в новом окне]

 

 

Важность: 5

Напишите функцию, getLocalDay(date) которая возвращает день недели для даты date.

День нужно возвратить в европейской нумерации, т.е. понедельник имеет номер 1, вторник номер 2, …, воскресенье - номер 7.

 

var date = new Date(2012, 0, 3);  // 3 янв 2012
alert( getLocalDay(date) );      // вторник, выведет 2

 

Решение

Решение - в использовании встроенной функции getDay. Она полностью подходит нашим целям, но для воскресенья возвращает 0 вместо 7:

 

   
01 function getLocalDay(date) {
02  
03   var day = date.getDay();
04  
05   if ( day == 0 ) { // день 0 становится 7
06     day = 7;
07   }
08    
09   return day;
10 }
11  
12 alert( getLocalDay(new Date(2012,0,3)) );  // 2

 

Если удобнее, чтобы день недели начинался с нуля, то можно возвращать в функции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. При этом если какая-то компонента не указана, она не меняется. Например:

 

   
1 var today = new Date;
2  
3 today.setHours(0);
4 alert( today ); // сегодня, но час изменен на 0
5  
6 today.setHours(0, 0, 0, 0);
7 alert (today ); // сегодня, ровно 00:00:00.

 

Автоисправление даты

Автоисправление — очень удобное свойство объектов Date. Оно заключается в том, что можно устанавливать заведомо некорректные компоненты (например 32 января), а объект сам себя поправит.

 

   
1 var d = new Date(2013, 0, 32); // 32 января 2013 ?!?
2 alert(d); // ... это 1 февраля 2013!

 

Неправильные компоненты даты автоматически распределяются по остальным.

Например, нужно увеличить на 2 дня дату «28 февраля 2011». Может быть так, что это будет 2 марта, а может быть и 1 марта, если год високосный. Но нам обо всем этом думать не нужно. Просто прибавляем два дня. Остальное сделает Date:

 

   
1 var d = new Date(2011, 1, 28);
2 d.setDate( d.getDate() + 2 );
3  
4 alert(d); // 2 марта, 2011

 

Также это используют для получения даты, отдаленной от имеющейся на нужный промежуток времени. Например, получим дату на 70 секунд большую текущей:

   
1 var d = new Date();
2 d.setSeconds( d.getSeconds()+70);
3  
4 alert(d); // выведет корректную дату

 

Можно установить и нулевые, и даже отрицательные компоненты. Например:

   
1 var d = new Date;
2  
3 d.setDate(1); // поставить первое число месяца
4 alert(d);
5  
6 d.setDate(0); // нулевого числа нет, будет последнее число предыдущего месяца
7 alert(d);

 

 

   
1 var d = new Date;
2  
3 d.setDate(-1); // предпоследнее число предыдущего месяца
4 alert(d);

 

 

Важность: 4

Какое число месяца было 100 дней назад? Какой день недели?

Используйте JavaScript, чтобы вывести эту информацию. Об этом говорит сайт https://intellect.icu . День недели выводите двухбуквенном виде, т.е. одно значение из (пн, вт, ср, …,вс).

Решение

Создадим текущую дату и вычтем 100 дней:

 

   
1 var d = new Date;
2 d.setDate( d.getDate() - 100 );
3  
4 alert( d.getDate() );
5  
6 var dayNames = ['вс','пн','вт','ср','чт','пт','сб'];
7 alert( dayNames[d.getDay()] );

 

Объект Date авто-исправит себя и выдаст правильный результат.

Обратите внимание на массив с именами дней недели. «Нулевой» день — воскресенье.

[Открыть задачу в новом окне]

Важность: 5

Напишите функцию getLastDayInMonth(year, month), которая возвращает последний день месяца.

Параметры:

  • year — 4-значный год, например 2012.
  • month — месяц от 0 до 11.

Например, getLastDayInMonth(2012, 1) = 29 (високосный год, февраль).

Решение

Создадим дату из следующего месяца, но день не первый, а «нулевой» (т.е. предыдущий):

 

   
1 function getLastDayOfMonth(year, month) {
2   var date = new Date(year, month+1, 0);
3   return date.getDate();
4 }
5  
6 alert( getLastDayOfMonth(2012, 1) ); // 29

 

[Открыть задачу в новом окне]

 

Преобразование к числу, разность дат

Когда объект Date используется в числовом контексте, он преобразуется в количество миллисекунд:

 

   
1 alert( +new Date ) // +date то же самое, что: +date.valueOf()

 

Важный побочный эффект: даты можно вычитать, результат вычитания объектов Date — их временная разница, в миллисекундах.

Это используют для измерения времени:

 

   
01 var start = new Date; // засекли время
02  
03 // что-то сделать
04 for (var i=0; i<100000; i++) {
05   var doSomething = i*i*i;
06 }
07  
08 var end = new Date; // конец измерения
09  
10 alert("Цикл занял " + (end-start) + " ms");

 

 

Важность: 5

Напишите код, который выводит:

  1. Сколько секунд прошло с начала сегодняшнего дня.
  2. Сколько осталось до конца дня.

Скрипт должен работать в любой день, т.е. в нем не должно быть конкретного значения сегодняшней даты.

Решение

Первая часть.

Для вывода достаточно сгенерировать date, соответствующий началу дня, т.е. «сегодня» 00 часов 00 минут 00 секунд.

Разница между текущей датой и началом дня — это количество миллисекунд от начала дня. Его можно легко перевести в секунды:

 

   
1 var now = new Date();
2  
3 // создать объект из текущей даты, без часов-минут-секунд
4 var today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
5  
6 var diff = now - today; // разница в миллисекундах
7 alert( Math.round(diff / 1000) ); // перевести в секунды

 

Вторая часть

Для получения оставшихся до конца дня секунд нужно из «завтра 00ч 00мин 00сек» вычесть текущее время.

Чтобы сгенерировать «завтра», нужно увеличить текущий день на 1:

 

   
1 var now = new Date();
2  
3 // создать объект из даты, без часов-минут-секунд
4 var tomorrow = new Date(now.getFullYear(), now.getMonth(),now.getDate()+1);
5  
6 var diff = tomorrow - now; // разница в миллисекундах
7 alert( Math.round(diff / 1000) ); // перевести в секунды

 

[Открыть задачу в новом окне]

 

Бенчмаркинг

Допустим, у нас есть несколько вариантов решения задачи, каждый описан функцией.

Как узнать, какой быстрее?

Для примера возьмем две функции, которые округляют число:

1 function floorMath(x) {
2   return Math.floor(x);
3 }
4  
5 function floorXor(x) {
6   return x^0; // побитовое исключающее ИЛИ (XOR) всегда округляет число
7 }

 

Чтобы померять, какая из них быстрее, нельзя запустить один раз floorMath, один раз floorXor и замерить разницу. Одноразовый запуск ненадежен, любая мини-помеха исказит результат.

Для правильного бенчмаркинга функция запускается много раз, чтобы сам тест занял существенное время. Это сведет влияние помех к минимуму. Сложную функцию можно запускать 100 раз, простую — 1000 раз…

Померяем, какая из функций округления быстрее:

 

   
01 function floorMath(x) { return Math.floor(x); }
02 function floorXor(x) { return x^0; }
03  
04 function bench(f) {
05   var date = new Date();
06   for (var i=0.5; i<1000000; i++) f(i);
07   return new Date() - date;
08 }
09  
10 alert('Время floorMath: ' + bench(floorMath) + 'мс');
11 alert('Время floorXor: ' + bench(floorXor) + 'мс');

 

В зависимости от браузера, может быть быстрее как floorXor так и floorMath.

Представим себе — во время первого бенчмаркинга bench(floorMath) компьютер что-то делал параллельно важное (вдруг) и это занимало ресурсы, а во время второго — перестал. Реальная ситуация? Конечно реальна, особенно на современных ОС.

Гораздо более надежные результаты можно получить, весь пакет тестов прогнать много раз.

 

   
01 function floorMath(x) { return Math.floor(x); }
02 function floorXor(x) { return x^0; }
03  
04 function bench(f) {
05   var date = new Date();
06   for (var i=0.5; i<100000; i++) f(i);
07   return new Date() - date;
08 }
09  
10 var timeMath = 0, timeXor = 0;
11 for(var i=0; i<100; i++) {
12   timeMath += bench(floorMath);
13   timeXor += bench(floorXor);
14 }
15  
16 alert('Время floorMath: ' + timeMath + 'мс');
17 alert('Время floorXor: ' +timeXor + 'мс');

 

Форматирование

Встроенные в Date методы форматирования используются редко, и преимущественно, для отладки.

toString()toDateString()toTimeString()
Возвращают стандартное строчное представление, не указанное в стандарте, а зависящее от браузера. Единственное требование - читаемость человеком. Метод toString возвращает дату целиком, toDateString() и toTimeString() - только дату и время соответственно.
   
1 var d = new Date();
2  
3 alert( d.toString() ); // вывод, похожий на 'Wed Jan 26 2011 16:40:50 GMT+0300'
toLocaleString()toLocaleDateString()toLocaleTimeString()
То же самое, но строка должна быть с учетом локальных настроек и языка посетителя.
   
1 var d = new Date();
2  
3 alert( d.toLocaleString() ); // дата на языке посетителя
toUTCString()
То же самое, что toString(), но дата в зоне UTC.
toISOString()
Возвращает дату в формате ISO Детали формата будут далее. Поддерживается современными браузерами, не поддерживается IE<9.

 

   
1 var d = new Date();
2  
3 alert( d.toISOString() ); // вывод, похожий на '2011-01-26T13:51:50.417Z'

 

Встроенные методы форматирования Date не допускают указание собственного формата.

Поэтому, как правило, любой вывод, кроме отладочного, форматируется своей, а не встроенной функцией.

 

Важность: 3

Напишите функцию formatDate(date), которая выводит дату date в формате дд.мм.гг:

Например:

var d = new Date(2011, 0, 30); // 30 января 2011
alert( formatDate(d) ); // '30.01.11'

 

P.S. Обратите внимание, ведущие нули должны присутствовать, то есть 1 января 2011 должно быть 01.01.11, а не 1.1.11.

Решение

Получим компоненты один за другим.

  1. День можно получить как date.getDate(). При необходимости добавим ведущий ноль:
    var dd = date.getDate();
    if (dd<10) dd= '0'+dd;
  2. date.getMonth() возвратит месяц, начиная с нуля. Увеличим его на 1:
    var mm = date.getMonth() + 1;  // месяц 1-12
    if (mm<10) mm= '0'+mm;
  3. date.getFullYear() вернет год в 4-значном формате. Чтобы сделать его двузначным - воспользуемся оператором взятия остатка '%':
    var yy = date.getFullYear() % 100;
    if (yy<10) yy= '0'+yy;
    Заметим, что год, как и другие компоненты, может понадобиться дополнить нулем слева, причем возможно что yy == 0 (например, 2000 год). При сложении со строкой 0+'0' == '00', так что будет все в порядке.

Полный код:

 

   
01 function formatDate(date) {
02  
03   var dd = date.getDate()
04   if ( dd < 10 ) dd = '0' + dd;
05  
06   var mm = date.getMonth()+1
07   if ( mm < 10 ) mm = '0' + mm;
08  
09   var yy = date.getFullYear() % 100;
10   if ( yy < 10 ) yy = '0' + yy;
11  
12   return dd+'.'+mm+'.'+yy;
13 }
14  
15 var d = new Date(2011, 0, 30);  // 30 Jan 2011
16 alert( formatDate(d) );  // '30.01.11'

 

[Открыть задачу в новом окне]

 

 

Важность: 4

Напишите функцию formatDate(date), которая форматирует дату dateтак:

  • Если со времени date прошло менее секунды, то возвращает "только что".
  • Иначе если со времени date прошло менее минуты, то "n сек. назад".
  • Иначе если прошло меньше часа, то "m мин. назад".
  • Иначе полная дата в формате "дд.мм.гг чч:мм".

Например:

1 function formatDate(date) { /* ваш код */ }
2  
3 alert( formatDate( new Date(new Date - 1) ) ); // "только что"
4  
5 alert( formatDate( new Date(new Date - 30*1000) ) ); // "30 сек. назад"
6  
7 alert( formatDate( new Date(new Date- 5*60*1000) ) ); // "5 мин. назад"
8  
9 alert( formatDate( new Date(new Date - 86400*1000) ) ); // вчерашняя дата в формате "дд.мм.гг чч:мм"

 

Решение

Для того, чтобы узнать время от date до текущего момента - используем вычитание дат.

 

   
01 function formatDate(date) {
02   var diff = new Date() - date; // разница в миллисекундах
03    
04   if (diff < 1000) { // прошло менее 1 секунды
05     return 'только что';
06   }
07  
08   var sec = Math.floor( diff / 1000 ); // округлить diff до секунд
09      
10   if (sec < 60) {
11     return sec + ' сек. назад';
12   }
13      
14   var min = Math.floor( diff / 60000 ); // округлить diff до минут
15   if (min < 60) {
16     return min + ' мин. назад';    
17   }
18  
19   // форматировать дату, с учетом того, что месяцы начинаются с 0
20   var d = date;
21   d = ['0'+d.getDate(),'0'+(d.getMonth()+1),''+d.getFullYear(),'0'+d.getHours(),'0'+d.getMinutes() ];
22   for(var i=0; i<d.length; i++) {
23     d[i] = d[i].slice(-2);
24   }
25  
26   return d.slice(0,3).join('.')+' '+d.slice(3).join(':');
27 }
28  
29 alert( formatDate( new Date( new Date - 1) ) ); // только что
30  
31 alert( formatDate( new Date( new Date - 30*1000) ) ); // 30 сек. назад
32  
33 alert( formatDate( new Date( new Date- 5*60*1000) ) ); // 5 мин. назад
34  
35 alert( formatDate( new Date( new Date - 86400*1000) ) ); // вчерашняя дата в формате "дд.мм.гг чч:мм"

 

[Открыть задачу в новом окне]

 

Разбор строки, Date.parse

Все современные браузеры, включая IE9+, понимают даты в упрощенном формате ISO 8601 Extended.

Этот формат выглядит так: YYYY-MM-DDTHH:mm:ss.sssZ. Для разделения даты и времени в нем используется символ 'T'. Часть 'Z' обозначает (необязательную) временную зону — она может отсутствовать, тогда зона UTC, либо может быть символ z — тоже UTC, или зона в формате +-hh:mm.

Также возможны упрощенные варианты, к примеру:

YYYY
YYYY-MM
YYYY-MM-DD
Метод Date.parse(str) разбирает строку str в таком формате и возвращает соответствующее ей количество миллисекунд. Если это невозможно, Date.parse возвращает NaN.

 

На момент написания некоторые браузеры (Safari) воспринимали формат без 'Z' как дату в локальной таймзоне (по стандарту UTC), поэтому пример ниже в них работает некорректно:

 

   
1 var msNoZone = Date.parse('2012-01-26T13:51:50.417'); // без зоны, значит UTC
2  
3 alert(msNoZone); // 1327571510417 (число миллисекунд)
4  
5 var msZ = Date.parse('2012-01-26T13:51:50.417z'); // зона z означает UTC
6 alert(msZ == msNoZone); // true, если браузер правильный

 

С таймзоной -07:00 GMT в конце все современные браузеры работают правильно:

 

   
1 var ms = Date.parse('2012-01-26T13:51:50.417-07:00');
2  
3 alert(ms); // 1327611110417 (число миллисекунд)

 

 

Формат дат для IE8-

До появления спецификации EcmaScript 5 формат не был стандартизован, и браузеры, включая IE8-, имели свои собственные форматы дат. Частично, эти форматы пересекаются.

Например, код ниже работает везде, включая старые IE:

 

   
1 var ms = Date.parse("January 26, 2011 13:51:50");
2  
3 alert(ms);

 

Вы также можете почитать о старых форматах IE в документации к методу MSDN Date.parse.

Конечно же, сейчас лучше использовать современный формат, если цель — современные браузеры, а если дополнительно нужны IE8-, то либо передавать даты через миллисекунды, а не строки, либо добавить библиотеку типа es5-shim, которая добавит Date.parse в старые IE.

 

Итого

  • Дата и время представлены в JavaScript одним объектом: Date. Создать «только время» при этом нельзя, оно должно быть с датой. Список методов Date вы можете найти в справочникеDate или выше.
  • Объект Date удобен тем, что автокорректируется. Благодаря этому легко сдвигать даты.
  • Объекты Date можно вычитать, результатом будет разница в мс.

К сожалению, в одной статье не просто дать все знания про дата в JS. Но я - старался. Если ты проявишь интерес к раскрытию подробностей,я обязательно напишу продолжение! Надеюсь, что теперь ты понял что такое дата в JS, время в JS и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)

создано: 2014-10-07
обновлено: 2024-11-14
372



Рейтиг 9 of 10. count vote: 2
Вы довольны ?:


Поделиться:

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выплнения задания
  • Возможно примерение функции гаранта на сделку
  • Приорететная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можите продать(исполнителем) или купить(заказчиком) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно примерение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей

Комментарии


Оставить комментарий
Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)

Термины: Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)