БлогNot. Простой календарь праздников на Javascript

Простой календарь праздников на Javascript

Ещё недавно на многих сайтах было очень модно выводить некие дополнительные сообщения, привязанные к текущей дате по часам компьютера посетителя, например, пару слов о том, какой нынче праздник. Сегодня такой функционал тоже не потерял актуальности и вряд ли когда-нибудь потеряет. Мы хотим реализовать максимально простой вариант кода, работающий без серверного программирования, то есть, на Javascript прямо из HTML-разметки документа.

Для простоты примем, что:

  • нас интересуют только даты в формате "день-месяц";
  • данные описаны статически в коде страницы и не нужно подгружать их удалённо.

Конечно, при желании эти ограничения можно преодолеть, расширив код. А в нашем случае и порядок действий, и код будут совсем несложны:

  • подготовить элемент, куда будет выводиться результат поиска праздника, у нас это раздел с идентификатором holidayId;
  • по событию загрузки страницы приготовить вызов функции-замыкания, названной checkHoliday, аргументом которой передан этот идентификатор;
  • написать функцию, в которой реализовать хранение массива объектов-праздников и код для интерфейса с этим массивом.

Вот соответствующий скрипт в работе и листингом, листинг нужно сохранять как файл типа .html в кодировке Юникода utf-8.

Сегодня нет праздника...

<!DOCTYPE html>
<html lang="ru">
 <head>
  <meta charset="utf-8" />
  <title>Праздники</title>
 </head>
 <body>

<div id="holidayId" style="background-color: #ccffcc">Сегодня нет праздника...</div>
<script>
 var checkHoliday = function (id) {
  var Holidays = [ //месяцы с единицы!
   //о каждом празднике в формате день, месяц, описание
   { day: 1, month: 1, desc: 'Новый год' },
   { day: 7, month: 1, desc: 'Рождество' },
   { day: 23, month: 2, desc: 'День Мужыка' },
   { day: 8, month: 3, desc: 'День Бабы' },
   { day: 1, month: 5, desc: 'Первомай' },
   { day: 9, month: 5, desc: 'День Победы' },
   { day: 23, month: 5, desc: 'ДР нашего любимого Одмина' },
   { day: 1, month: 6, desc: 'День защиты детей' },
   { day: 1, month: 9, desc: 'День знаний' },
   { day: 7, month: 11, desc: 'День большевичка' },
   { day: 31, month: 12, desc: 'Новый год' }
  ];
  function today () { //сегодняшняя дата в формате { day: 31, month: 12 }
   var t = new Date();
   var d = t.getDate();
   var m = t.getMonth() + 1;
   return { day: d, month: m };
  }
  function check (t) { //поиск праздника, вернём его номер в списке или -1
   for (var i=0; i<Holidays.length; i++)
    if (Holidays[i].day == t.day && Holidays[i].month == t.month) return i;
   return -1;
  }
  function strDate (t) { //дата t в формате "31 декабря"
   var monthes = [ '','января','февраля','марта','апреля','мая','июня',
   'июля','августа','сентября','октября','ноября','декабря' ];
   return t.day + ' ' + monthes[t.month];
  }
  var t = today();
  var k = check(t);
  if (k > -1) { //если найдено
   var el = document.getElementById (id);
   el.innerHTML = strDate(t)+': '+Holidays[k].desc;
  }
 } 
 window.addEventListener('load', function (e) { 
  checkHoliday('holidayId'); //передать id элемента, куда пишем!
 });  
</script>
<noscript>Нужен включённый в браузере Javascript для работы приложения!</noscript>

</body></html>

Вот кодик, чтобы сделать в элементе с id="data" список-заготовку всех дней года в формате "день-месяц" для первого скрипта. В получившемся списке данные корректно выровнены, остаётся только заполнить описания дней desc внутри одинарных кавычек.

<pre><div id="data"></div></pre>
<script>
 var listOfDays = function (id) {
  var list = 'var Holidays = [';
  var days = [31,29,31,30,31,30,31,31,30,31,30,31];
  for (var m=0; m<12; m++) {
   for (var d=1; d<=days[m]; d++) {
    list += "\n" + ' { day: '+ (d<10 ? ' ' : '') + d + 
            ', month: '+(m<9 ? ' ' : '') + (m+1) + ', desc: \'\' }' +
            (m==11 && d==31 ? '' : ',');
   }
  }
  list += "\n" + '];'
  document.getElementById (id).innerHTML = list;
 }

 window.addEventListener('load', function (e) { 
  listOfDays('data'); //передать id элемента, куда пишем!
 });  
</script>
<noscript>Нужен включённый в браузере Javascript для работы приложения!</noscript>

Вот результат работы этого скрипта, если выполнить его из файла .html:

var Holidays = [
 { day:  1, month:  1, desc: '' },
 { day:  2, month:  1, desc: '' },
 { day:  3, month:  1, desc: '' },
 { day:  4, month:  1, desc: '' },
 { day:  5, month:  1, desc: '' },
 { day:  6, month:  1, desc: '' },
 { day:  7, month:  1, desc: '' },
 { day:  8, month:  1, desc: '' },
 { day:  9, month:  1, desc: '' },
 { day: 10, month:  1, desc: '' },
 { day: 11, month:  1, desc: '' },
 { day: 12, month:  1, desc: '' },
 { day: 13, month:  1, desc: '' },
 { day: 14, month:  1, desc: '' },
 { day: 15, month:  1, desc: '' },
 { day: 16, month:  1, desc: '' },
 { day: 17, month:  1, desc: '' },
 { day: 18, month:  1, desc: '' },
 { day: 19, month:  1, desc: '' },
 { day: 20, month:  1, desc: '' },
 { day: 21, month:  1, desc: '' },
 { day: 22, month:  1, desc: '' },
 { day: 23, month:  1, desc: '' },
 { day: 24, month:  1, desc: '' },
 { day: 25, month:  1, desc: '' },
 { day: 26, month:  1, desc: '' },
 { day: 27, month:  1, desc: '' },
 { day: 28, month:  1, desc: '' },
 { day: 29, month:  1, desc: '' },
 { day: 30, month:  1, desc: '' },
 { day: 31, month:  1, desc: '' },
 { day:  1, month:  2, desc: '' },
 { day:  2, month:  2, desc: '' },
 { day:  3, month:  2, desc: '' },
 { day:  4, month:  2, desc: '' },
 { day:  5, month:  2, desc: '' },
 { day:  6, month:  2, desc: '' },
 { day:  7, month:  2, desc: '' },
 { day:  8, month:  2, desc: '' },
 { day:  9, month:  2, desc: '' },
 { day: 10, month:  2, desc: '' },
 { day: 11, month:  2, desc: '' },
 { day: 12, month:  2, desc: '' },
 { day: 13, month:  2, desc: '' },
 { day: 14, month:  2, desc: '' },
 { day: 15, month:  2, desc: '' },
 { day: 16, month:  2, desc: '' },
 { day: 17, month:  2, desc: '' },
 { day: 18, month:  2, desc: '' },
 { day: 19, month:  2, desc: '' },
 { day: 20, month:  2, desc: '' },
 { day: 21, month:  2, desc: '' },
 { day: 22, month:  2, desc: '' },
 { day: 23, month:  2, desc: '' },
 { day: 24, month:  2, desc: '' },
 { day: 25, month:  2, desc: '' },
 { day: 26, month:  2, desc: '' },
 { day: 27, month:  2, desc: '' },
 { day: 28, month:  2, desc: '' },
 { day: 29, month:  2, desc: '' },
 { day:  1, month:  3, desc: '' },
 { day:  2, month:  3, desc: '' },
 { day:  3, month:  3, desc: '' },
 { day:  4, month:  3, desc: '' },
 { day:  5, month:  3, desc: '' },
 { day:  6, month:  3, desc: '' },
 { day:  7, month:  3, desc: '' },
 { day:  8, month:  3, desc: '' },
 { day:  9, month:  3, desc: '' },
 { day: 10, month:  3, desc: '' },
 { day: 11, month:  3, desc: '' },
 { day: 12, month:  3, desc: '' },
 { day: 13, month:  3, desc: '' },
 { day: 14, month:  3, desc: '' },
 { day: 15, month:  3, desc: '' },
 { day: 16, month:  3, desc: '' },
 { day: 17, month:  3, desc: '' },
 { day: 18, month:  3, desc: '' },
 { day: 19, month:  3, desc: '' },
 { day: 20, month:  3, desc: '' },
 { day: 21, month:  3, desc: '' },
 { day: 22, month:  3, desc: '' },
 { day: 23, month:  3, desc: '' },
 { day: 24, month:  3, desc: '' },
 { day: 25, month:  3, desc: '' },
 { day: 26, month:  3, desc: '' },
 { day: 27, month:  3, desc: '' },
 { day: 28, month:  3, desc: '' },
 { day: 29, month:  3, desc: '' },
 { day: 30, month:  3, desc: '' },
 { day: 31, month:  3, desc: '' },
 { day:  1, month:  4, desc: '' },
 { day:  2, month:  4, desc: '' },
 { day:  3, month:  4, desc: '' },
 { day:  4, month:  4, desc: '' },
 { day:  5, month:  4, desc: '' },
 { day:  6, month:  4, desc: '' },
 { day:  7, month:  4, desc: '' },
 { day:  8, month:  4, desc: '' },
 { day:  9, month:  4, desc: '' },
 { day: 10, month:  4, desc: '' },
 { day: 11, month:  4, desc: '' },
 { day: 12, month:  4, desc: '' },
 { day: 13, month:  4, desc: '' },
 { day: 14, month:  4, desc: '' },
 { day: 15, month:  4, desc: '' },
 { day: 16, month:  4, desc: '' },
 { day: 17, month:  4, desc: '' },
 { day: 18, month:  4, desc: '' },
 { day: 19, month:  4, desc: '' },
 { day: 20, month:  4, desc: '' },
 { day: 21, month:  4, desc: '' },
 { day: 22, month:  4, desc: '' },
 { day: 23, month:  4, desc: '' },
 { day: 24, month:  4, desc: '' },
 { day: 25, month:  4, desc: '' },
 { day: 26, month:  4, desc: '' },
 { day: 27, month:  4, desc: '' },
 { day: 28, month:  4, desc: '' },
 { day: 29, month:  4, desc: '' },
 { day: 30, month:  4, desc: '' },
 { day:  1, month:  5, desc: '' },
 { day:  2, month:  5, desc: '' },
 { day:  3, month:  5, desc: '' },
 { day:  4, month:  5, desc: '' },
 { day:  5, month:  5, desc: '' },
 { day:  6, month:  5, desc: '' },
 { day:  7, month:  5, desc: '' },
 { day:  8, month:  5, desc: '' },
 { day:  9, month:  5, desc: '' },
 { day: 10, month:  5, desc: '' },
 { day: 11, month:  5, desc: '' },
 { day: 12, month:  5, desc: '' },
 { day: 13, month:  5, desc: '' },
 { day: 14, month:  5, desc: '' },
 { day: 15, month:  5, desc: '' },
 { day: 16, month:  5, desc: '' },
 { day: 17, month:  5, desc: '' },
 { day: 18, month:  5, desc: '' },
 { day: 19, month:  5, desc: '' },
 { day: 20, month:  5, desc: '' },
 { day: 21, month:  5, desc: '' },
 { day: 22, month:  5, desc: '' },
 { day: 23, month:  5, desc: '' },
 { day: 24, month:  5, desc: '' },
 { day: 25, month:  5, desc: '' },
 { day: 26, month:  5, desc: '' },
 { day: 27, month:  5, desc: '' },
 { day: 28, month:  5, desc: '' },
 { day: 29, month:  5, desc: '' },
 { day: 30, month:  5, desc: '' },
 { day: 31, month:  5, desc: '' },
 { day:  1, month:  6, desc: '' },
 { day:  2, month:  6, desc: '' },
 { day:  3, month:  6, desc: '' },
 { day:  4, month:  6, desc: '' },
 { day:  5, month:  6, desc: '' },
 { day:  6, month:  6, desc: '' },
 { day:  7, month:  6, desc: '' },
 { day:  8, month:  6, desc: '' },
 { day:  9, month:  6, desc: '' },
 { day: 10, month:  6, desc: '' },
 { day: 11, month:  6, desc: '' },
 { day: 12, month:  6, desc: '' },
 { day: 13, month:  6, desc: '' },
 { day: 14, month:  6, desc: '' },
 { day: 15, month:  6, desc: '' },
 { day: 16, month:  6, desc: '' },
 { day: 17, month:  6, desc: '' },
 { day: 18, month:  6, desc: '' },
 { day: 19, month:  6, desc: '' },
 { day: 20, month:  6, desc: '' },
 { day: 21, month:  6, desc: '' },
 { day: 22, month:  6, desc: '' },
 { day: 23, month:  6, desc: '' },
 { day: 24, month:  6, desc: '' },
 { day: 25, month:  6, desc: '' },
 { day: 26, month:  6, desc: '' },
 { day: 27, month:  6, desc: '' },
 { day: 28, month:  6, desc: '' },
 { day: 29, month:  6, desc: '' },
 { day: 30, month:  6, desc: '' },
 { day:  1, month:  7, desc: '' },
 { day:  2, month:  7, desc: '' },
 { day:  3, month:  7, desc: '' },
 { day:  4, month:  7, desc: '' },
 { day:  5, month:  7, desc: '' },
 { day:  6, month:  7, desc: '' },
 { day:  7, month:  7, desc: '' },
 { day:  8, month:  7, desc: '' },
 { day:  9, month:  7, desc: '' },
 { day: 10, month:  7, desc: '' },
 { day: 11, month:  7, desc: '' },
 { day: 12, month:  7, desc: '' },
 { day: 13, month:  7, desc: '' },
 { day: 14, month:  7, desc: '' },
 { day: 15, month:  7, desc: '' },
 { day: 16, month:  7, desc: '' },
 { day: 17, month:  7, desc: '' },
 { day: 18, month:  7, desc: '' },
 { day: 19, month:  7, desc: '' },
 { day: 20, month:  7, desc: '' },
 { day: 21, month:  7, desc: '' },
 { day: 22, month:  7, desc: '' },
 { day: 23, month:  7, desc: '' },
 { day: 24, month:  7, desc: '' },
 { day: 25, month:  7, desc: '' },
 { day: 26, month:  7, desc: '' },
 { day: 27, month:  7, desc: '' },
 { day: 28, month:  7, desc: '' },
 { day: 29, month:  7, desc: '' },
 { day: 30, month:  7, desc: '' },
 { day: 31, month:  7, desc: '' },
 { day:  1, month:  8, desc: '' },
 { day:  2, month:  8, desc: '' },
 { day:  3, month:  8, desc: '' },
 { day:  4, month:  8, desc: '' },
 { day:  5, month:  8, desc: '' },
 { day:  6, month:  8, desc: '' },
 { day:  7, month:  8, desc: '' },
 { day:  8, month:  8, desc: '' },
 { day:  9, month:  8, desc: '' },
 { day: 10, month:  8, desc: '' },
 { day: 11, month:  8, desc: '' },
 { day: 12, month:  8, desc: '' },
 { day: 13, month:  8, desc: '' },
 { day: 14, month:  8, desc: '' },
 { day: 15, month:  8, desc: '' },
 { day: 16, month:  8, desc: '' },
 { day: 17, month:  8, desc: '' },
 { day: 18, month:  8, desc: '' },
 { day: 19, month:  8, desc: '' },
 { day: 20, month:  8, desc: '' },
 { day: 21, month:  8, desc: '' },
 { day: 22, month:  8, desc: '' },
 { day: 23, month:  8, desc: '' },
 { day: 24, month:  8, desc: '' },
 { day: 25, month:  8, desc: '' },
 { day: 26, month:  8, desc: '' },
 { day: 27, month:  8, desc: '' },
 { day: 28, month:  8, desc: '' },
 { day: 29, month:  8, desc: '' },
 { day: 30, month:  8, desc: '' },
 { day: 31, month:  8, desc: '' },
 { day:  1, month:  9, desc: '' },
 { day:  2, month:  9, desc: '' },
 { day:  3, month:  9, desc: '' },
 { day:  4, month:  9, desc: '' },
 { day:  5, month:  9, desc: '' },
 { day:  6, month:  9, desc: '' },
 { day:  7, month:  9, desc: '' },
 { day:  8, month:  9, desc: '' },
 { day:  9, month:  9, desc: '' },
 { day: 10, month:  9, desc: '' },
 { day: 11, month:  9, desc: '' },
 { day: 12, month:  9, desc: '' },
 { day: 13, month:  9, desc: '' },
 { day: 14, month:  9, desc: '' },
 { day: 15, month:  9, desc: '' },
 { day: 16, month:  9, desc: '' },
 { day: 17, month:  9, desc: '' },
 { day: 18, month:  9, desc: '' },
 { day: 19, month:  9, desc: '' },
 { day: 20, month:  9, desc: '' },
 { day: 21, month:  9, desc: '' },
 { day: 22, month:  9, desc: '' },
 { day: 23, month:  9, desc: '' },
 { day: 24, month:  9, desc: '' },
 { day: 25, month:  9, desc: '' },
 { day: 26, month:  9, desc: '' },
 { day: 27, month:  9, desc: '' },
 { day: 28, month:  9, desc: '' },
 { day: 29, month:  9, desc: '' },
 { day: 30, month:  9, desc: '' },
 { day:  1, month: 10, desc: '' },
 { day:  2, month: 10, desc: '' },
 { day:  3, month: 10, desc: '' },
 { day:  4, month: 10, desc: '' },
 { day:  5, month: 10, desc: '' },
 { day:  6, month: 10, desc: '' },
 { day:  7, month: 10, desc: '' },
 { day:  8, month: 10, desc: '' },
 { day:  9, month: 10, desc: '' },
 { day: 10, month: 10, desc: '' },
 { day: 11, month: 10, desc: '' },
 { day: 12, month: 10, desc: '' },
 { day: 13, month: 10, desc: '' },
 { day: 14, month: 10, desc: '' },
 { day: 15, month: 10, desc: '' },
 { day: 16, month: 10, desc: '' },
 { day: 17, month: 10, desc: '' },
 { day: 18, month: 10, desc: '' },
 { day: 19, month: 10, desc: '' },
 { day: 20, month: 10, desc: '' },
 { day: 21, month: 10, desc: '' },
 { day: 22, month: 10, desc: '' },
 { day: 23, month: 10, desc: '' },
 { day: 24, month: 10, desc: '' },
 { day: 25, month: 10, desc: '' },
 { day: 26, month: 10, desc: '' },
 { day: 27, month: 10, desc: '' },
 { day: 28, month: 10, desc: '' },
 { day: 29, month: 10, desc: '' },
 { day: 30, month: 10, desc: '' },
 { day: 31, month: 10, desc: '' },
 { day:  1, month: 11, desc: '' },
 { day:  2, month: 11, desc: '' },
 { day:  3, month: 11, desc: '' },
 { day:  4, month: 11, desc: '' },
 { day:  5, month: 11, desc: '' },
 { day:  6, month: 11, desc: '' },
 { day:  7, month: 11, desc: '' },
 { day:  8, month: 11, desc: '' },
 { day:  9, month: 11, desc: '' },
 { day: 10, month: 11, desc: '' },
 { day: 11, month: 11, desc: '' },
 { day: 12, month: 11, desc: '' },
 { day: 13, month: 11, desc: '' },
 { day: 14, month: 11, desc: '' },
 { day: 15, month: 11, desc: '' },
 { day: 16, month: 11, desc: '' },
 { day: 17, month: 11, desc: '' },
 { day: 18, month: 11, desc: '' },
 { day: 19, month: 11, desc: '' },
 { day: 20, month: 11, desc: '' },
 { day: 21, month: 11, desc: '' },
 { day: 22, month: 11, desc: '' },
 { day: 23, month: 11, desc: '' },
 { day: 24, month: 11, desc: '' },
 { day: 25, month: 11, desc: '' },
 { day: 26, month: 11, desc: '' },
 { day: 27, month: 11, desc: '' },
 { day: 28, month: 11, desc: '' },
 { day: 29, month: 11, desc: '' },
 { day: 30, month: 11, desc: '' },
 { day:  1, month: 12, desc: '' },
 { day:  2, month: 12, desc: '' },
 { day:  3, month: 12, desc: '' },
 { day:  4, month: 12, desc: '' },
 { day:  5, month: 12, desc: '' },
 { day:  6, month: 12, desc: '' },
 { day:  7, month: 12, desc: '' },
 { day:  8, month: 12, desc: '' },
 { day:  9, month: 12, desc: '' },
 { day: 10, month: 12, desc: '' },
 { day: 11, month: 12, desc: '' },
 { day: 12, month: 12, desc: '' },
 { day: 13, month: 12, desc: '' },
 { day: 14, month: 12, desc: '' },
 { day: 15, month: 12, desc: '' },
 { day: 16, month: 12, desc: '' },
 { day: 17, month: 12, desc: '' },
 { day: 18, month: 12, desc: '' },
 { day: 19, month: 12, desc: '' },
 { day: 20, month: 12, desc: '' },
 { day: 21, month: 12, desc: '' },
 { day: 22, month: 12, desc: '' },
 { day: 23, month: 12, desc: '' },
 { day: 24, month: 12, desc: '' },
 { day: 25, month: 12, desc: '' },
 { day: 26, month: 12, desc: '' },
 { day: 27, month: 12, desc: '' },
 { day: 28, month: 12, desc: '' },
 { day: 29, month: 12, desc: '' },
 { day: 30, month: 12, desc: '' },
 { day: 31, month: 12, desc: '' }
];

Вот версия календаря (без внешнего HTML-обрамления документа), где массив праздников на весь год частично заполнен, снабжён символами "категорий" праздника, а также выводом сообщений о ближайшем празднике с учётом перехода через год. Проверьте, что для високосного года нет неточностей со словами "завтра"-"послезавтра" и т.п.

<div id="holidayId" style="background-color: #ccffcc; width: 100%; margin: 0 auto; padding: 4px;"></div>
<script>
(function checkHoliday(id) {
  var Holidays = [
 { day:  1, month:  1, desc: '&starf; Новый год' },
 { day:  2, month:  1, desc: '&ecolon; Новогодний опохмел' },
 { day:  3, month:  1, desc: '&ecolon; Новогодний опохмел' },
 { day:  4, month:  1, desc: '&ecolon; Новогодний опохмел' },
 { day:  5, month:  1, desc: '&ecolon; Новогодний опохмел' },
 { day:  6, month:  1, desc: '&ecolon; Новогодний опохмел. Анька' },
 { day:  7, month:  1, desc: '&dagger; Рождество Христово' },
 { day:  8, month:  1, desc: '&ecolon; Рождественский опохмел' },
 { day:  9, month:  1, desc: '&starf; Кровавое воскресенье' },
 { day: 10, month:  1, desc: '' },
 { day: 11, month:  1, desc: '&check; День Спасибо' },
 { day: 12, month:  1, desc: '' },
 { day: 13, month:  1, desc: '' },
 { day: 14, month:  1, desc: '&dagger; Старый новый год' },
 { day: 15, month:  1, desc: '' },
 { day: 16, month:  1, desc: '&check; День снеговика' },
 { day: 17, month:  1, desc: '' },
 { day: 18, month:  1, desc: '' },
 { day: 19, month:  1, desc: '&dagger; Крещение Господне' },
 { day: 20, month:  1, desc: '' },
 { day: 21, month:  1, desc: '&starf; Святое Околевание Мумии' },
 { day: 22, month:  1, desc: '' },
 { day: 23, month:  1, desc: '' },
 { day: 24, month:  1, desc: '' },
 { day: 25, month:  1, desc: '&check; День студента' },
 { day: 26, month:  1, desc: '' },
 { day: 27, month:  1, desc: '&check; День рождения лампочки' },
 { day: 28, month:  1, desc: '' },
 { day: 29, month:  1, desc: '&check; День изобретения автомобиля' },
 { day: 30, month:  1, desc: '' },
 { day: 31, month:  1, desc: '&hearts; День русской водки' },
 { day:  1, month:  2, desc: '&hearts; Февраль. Доставание чернил и плач' },
 { day:  2, month:  2, desc: '' },
 { day:  3, month:  2, desc: '' },
 { day:  4, month:  2, desc: '&check; День домашнего супа' },
 { day:  5, month:  2, desc: '' },
 { day:  6, month:  2, desc: '' },
 { day:  7, month:  2, desc: '' },
 { day:  8, month:  2, desc: '&check; День памяти российской науки' },
 { day:  9, month:  2, desc: '' },
 { day: 10, month:  2, desc: '' },
 { day: 11, month:  2, desc: '' },
 { day: 12, month:  2, desc: '' },
 { day: 13, month:  2, desc: '' },
 { day: 14, month:  2, desc: '&equiv; День Святой Валентины' },
 { day: 15, month:  2, desc: '' },
 { day: 16, month:  2, desc: '&hearts; ДР Златы' },
 { day: 17, month:  2, desc: '' },
 { day: 18, month:  2, desc: '' },
 { day: 19, month:  2, desc: '' },
 { day: 20, month:  2, desc: '&check; День справедливости' },
 { day: 21, month:  2, desc: '' },
 { day: 22, month:  2, desc: '' },
 { day: 23, month:  2, desc: '&starf; День Мужыка' },
 { day: 24, month:  2, desc: '' },
 { day: 25, month:  2, desc: '&check; День револьвера' },
 { day: 26, month:  2, desc: '' },
 { day: 27, month:  2, desc: '' },
 { day: 28, month:  2, desc: '' },
 { day: 29, month:  2, desc: '&hearts; День св. Тиба. Дядин день' },
 { day:  1, month:  3, desc: '&check; День кота' },
 { day:  2, month:  3, desc: '' },
 { day:  3, month:  3, desc: '&check; День дикой природы' },
 { day:  4, month:  3, desc: '' },
 { day:  5, month:  3, desc: '' },
 { day:  6, month:  3, desc: '' },
 { day:  7, month:  3, desc: '' },
 { day:  8, month:  3, desc: '&starf; День Бабы' },
 { day:  9, month:  3, desc: '' },
 { day: 10, month:  3, desc: '' },
 { day: 11, month:  3, desc: '' },
 { day: 12, month:  3, desc: '' },
 { day: 13, month:  3, desc: '' },
 { day: 14, month:  3, desc: '&hearts; День Пи! И Светы' },
 { day: 15, month:  3, desc: '' },
 { day: 16, month:  3, desc: '' },
 { day: 17, month:  3, desc: '' },
 { day: 18, month:  3, desc: '' },
 { day: 19, month:  3, desc: '' },
 { day: 20, month:  3, desc: '' },
 { day: 21, month:  3, desc: '' },
 { day: 22, month:  3, desc: '' },
 { day: 23, month:  3, desc: '' },
 { day: 24, month:  3, desc: '&hearts; День Сибирских Партизан' },
 { day: 25, month:  3, desc: '&check; День работника культуры' },
 { day: 26, month:  3, desc: '' },
 { day: 27, month:  3, desc: '&check; День театра' },
 { day: 28, month:  3, desc: '' },
 { day: 29, month:  3, desc: '' },
 { day: 30, month:  3, desc: '' },
 { day: 31, month:  3, desc: '' },
 { day:  1, month:  4, desc: '&equiv; День Дурака, главный праздник страны!' },
 { day:  2, month:  4, desc: '' },
 { day:  3, month:  4, desc: '' },
 { day:  4, month:  4, desc: '&check; День 404. День крысы' },
 { day:  5, month:  4, desc: '' },
 { day:  6, month:  4, desc: '' },
 { day:  7, month:  4, desc: '&check; День здоровья' },
 { day:  8, month:  4, desc: '' },
 { day:  9, month:  4, desc: '' },
 { day: 10, month:  4, desc: '' },
 { day: 11, month:  4, desc: '' },
 { day: 12, month:  4, desc: '&starf; День космонавтики' },
 { day: 13, month:  4, desc: '' },
 { day: 14, month:  4, desc: '' },
 { day: 15, month:  4, desc: '' },
 { day: 16, month:  4, desc: '' },
 { day: 17, month:  4, desc: '' },
 { day: 18, month:  4, desc: '' },
 { day: 19, month:  4, desc: '' },
 { day: 20, month:  4, desc: '' },
 { day: 21, month:  4, desc: '' },
 { day: 22, month:  4, desc: '&starf; ДР дедушки Ленина. &check; День Земли' },
 { day: 23, month:  4, desc: '' },
 { day: 24, month:  4, desc: '' },
 { day: 25, month:  4, desc: '&check; День ДНК' },
 { day: 26, month:  4, desc: '' },
 { day: 27, month:  4, desc: '' },
 { day: 28, month:  4, desc: '' },
 { day: 29, month:  4, desc: '&hearts; Иро, налевай!' },
 { day: 30, month:  4, desc: '' },
 { day:  1, month:  5, desc: '&starf; Первомай - наливай' },
 { day:  2, month:  5, desc: '' },
 { day:  3, month:  5, desc: '&check; День Солнца' },
 { day:  4, month:  5, desc: '' },
 { day:  5, month:  5, desc: '&starf; День совковой печати' },
 { day:  6, month:  5, desc: '' },
 { day:  7, month:  5, desc: '&starf; День радио' },
 { day:  8, month:  5, desc: '' },
 { day:  9, month:  5, desc: '&starf; День Победы' },
 { day: 10, month:  5, desc: '' },
 { day: 11, month:  5, desc: '' },
 { day: 12, month:  5, desc: '' },
 { day: 13, month:  5, desc: '' },
 { day: 14, month:  5, desc: '' },
 { day: 15, month:  5, desc: '&check; День семей' },
 { day: 16, month:  5, desc: '' },
 { day: 17, month:  5, desc: '' },
 { day: 18, month:  5, desc: '' },
 { day: 19, month:  5, desc: '&starf; День савеццкой пионерии :)' },
 { day: 20, month:  5, desc: '' },
 { day: 21, month:  5, desc: '' },
 { day: 22, month:  5, desc: '' },
 { day: 23, month:  5, desc: '&hearts; ДР нашего дорогого Одмина' },
 { day: 24, month:  5, desc: '' },
 { day: 25, month:  5, desc: '' },
 { day: 26, month:  5, desc: '' },
 { day: 27, month:  5, desc: '&check; День библиотекаря' },
 { day: 28, month:  5, desc: '' },
 { day: 29, month:  5, desc: '' },
 { day: 30, month:  5, desc: '' },
 { day: 31, month:  5, desc: '' },
 { day:  1, month:  6, desc: '&starf; День защиты детей от жизни' },
 { day:  2, month:  6, desc: '' },
 { day:  3, month:  6, desc: '' },
 { day:  4, month:  6, desc: '' },
 { day:  5, month:  6, desc: '' },
 { day:  6, month:  6, desc: '&check; Пушкинский день' },
 { day:  7, month:  6, desc: '' },
 { day:  8, month:  6, desc: '' },
 { day:  9, month:  6, desc: '&check; День друзей' },
 { day: 10, month:  6, desc: '' },
 { day: 11, month:  6, desc: '' },
 { day: 12, month:  6, desc: '&equiv; День пазорища Эльцына' },
 { day: 13, month:  6, desc: '' },
 { day: 14, month:  6, desc: '' },
 { day: 15, month:  6, desc: '&check; День ветра и мыльных пузырей' },
 { day: 16, month:  6, desc: '' },
 { day: 17, month:  6, desc: '&check; День борьбы с засухой' },
 { day: 18, month:  6, desc: '' },
 { day: 19, month:  6, desc: '' },
 { day: 20, month:  6, desc: '&check; День защиты слона' },
 { day: 21, month:  6, desc: '' },
 { day: 22, month:  6, desc: '&hearts; Летнее солнцестояние, самый длинный день в году' },
 { day: 23, month:  6, desc: '' },
 { day: 24, month:  6, desc: '' },
 { day: 25, month:  6, desc: '&check; День славян' },
 { day: 26, month:  6, desc: '' },
 { day: 27, month:  6, desc: '' },
 { day: 28, month:  6, desc: '' },
 { day: 29, month:  6, desc: '' },
 { day: 30, month:  6, desc: '' },
 { day:  1, month:  7, desc: '&hearts; Водпуск фарева' },
 { day:  2, month:  7, desc: '' },
 { day:  3, month:  7, desc: '&check; День гайца' },
 { day:  4, month:  7, desc: '' },
 { day:  5, month:  7, desc: '' },
 { day:  6, month:  7, desc: '&check; День поцелуев' },
 { day:  7, month:  7, desc: '&equiv; День утопленника' },
 { day:  8, month:  7, desc: '' },
 { day:  9, month:  7, desc: '' },
 { day: 10, month:  7, desc: '' },
 { day: 11, month:  7, desc: '' },
 { day: 12, month:  7, desc: '&check; День Петра и Павла' },
 { day: 13, month:  7, desc: '' },
 { day: 14, month:  7, desc: '&check; День взятия Бастилии' },
 { day: 15, month:  7, desc: '' },
 { day: 16, month:  7, desc: '&hearts; Alice, ДР' },
 { day: 17, month:  7, desc: '' },
 { day: 18, month:  7, desc: '' },
 { day: 19, month:  7, desc: '' },
 { day: 20, month:  7, desc: '&check; День шахмат' },
 { day: 21, month:  7, desc: '' },
 { day: 22, month:  7, desc: '' },
 { day: 23, month:  7, desc: '&check; День кита и дельфина' },
 { day: 24, month:  7, desc: '' },
 { day: 25, month:  7, desc: '' },
 { day: 26, month:  7, desc: '' },
 { day: 27, month:  7, desc: '' },
 { day: 28, month:  7, desc: '' },
 { day: 29, month:  7, desc: '' },
 { day: 30, month:  7, desc: '' },
 { day: 31, month:  7, desc: '' },
 { day:  1, month:  8, desc: '' },
 { day:  2, month:  8, desc: '&hearts; Ильин день' },
 { day:  3, month:  8, desc: '' },
 { day:  4, month:  8, desc: '' },
 { day:  5, month:  8, desc: '&check; День светофора' },
 { day:  6, month:  8, desc: '' },
 { day:  7, month:  8, desc: '' },
 { day:  8, month:  8, desc: '&check; День холодильника' },
 { day:  9, month:  8, desc: '' },
 { day: 10, month:  8, desc: '' },
 { day: 11, month:  8, desc: '' },
 { day: 12, month:  8, desc: '' },
 { day: 13, month:  8, desc: '' },
 { day: 14, month:  8, desc: '&hearts; День золотого сечения' },
 { day: 15, month:  8, desc: '' },
 { day: 16, month:  8, desc: '&check; Малинник' },
 { day: 17, month:  8, desc: '' },
 { day: 18, month:  8, desc: '' },
 { day: 19, month:  8, desc: '' },
 { day: 20, month:  8, desc: '' },
 { day: 21, month:  8, desc: '' },
 { day: 22, month:  8, desc: '' },
 { day: 23, month:  8, desc: '' },
 { day: 24, month:  8, desc: '' },
 { day: 25, month:  8, desc: '&hearts; ДР бабушки' },
 { day: 26, month:  8, desc: '' },
 { day: 27, month:  8, desc: '' },
 { day: 28, month:  8, desc: '' },
 { day: 29, month:  8, desc: '' },
 { day: 30, month:  8, desc: '' },
 { day: 31, month:  8, desc: '' },
 { day:  1, month:  9, desc: '&starf; День Незнайки' },
 { day:  2, month:  9, desc: '' },
 { day:  3, month:  9, desc: '' },
 { day:  4, month:  9, desc: '&hearts; Янкин день' },
 { day:  5, month:  9, desc: '' },
 { day:  6, month:  9, desc: '' },
 { day:  7, month:  9, desc: '' },
 { day:  8, month:  9, desc: '' },
 { day:  9, month:  9, desc: '' },
 { day: 10, month:  9, desc: '' },
 { day: 11, month:  9, desc: '' },
 { day: 12, month:  9, desc: '' },
 { day: 13, month:  9, desc: '&equiv; День программиста' },
 { day: 14, month:  9, desc: '' },
 { day: 15, month:  9, desc: '' },
 { day: 16, month:  9, desc: '&hearts; День знакомств' },
 { day: 17, month:  9, desc: '' },
 { day: 18, month:  9, desc: '' },
 { day: 19, month:  9, desc: '&check; День смайлика' },
 { day: 20, month:  9, desc: '' },
 { day: 21, month:  9, desc: '' },
 { day: 22, month:  9, desc: '' },
 { day: 23, month:  9, desc: '' },
 { day: 24, month:  9, desc: '' },
 { day: 25, month:  9, desc: '' },
 { day: 26, month:  9, desc: '' },
 { day: 27, month:  9, desc: '&check; День туризма' },
 { day: 28, month:  9, desc: '' },
 { day: 29, month:  9, desc: '' },
 { day: 30, month:  9, desc: '&check; День рунетика' },
 { day:  1, month: 10, desc: '' },
 { day:  2, month: 10, desc: '' },
 { day:  3, month: 10, desc: '' },
 { day:  4, month: 10, desc: '&check; День защиты животных' },
 { day:  5, month: 10, desc: '&check; День учителя' },
 { day:  6, month: 10, desc: '' },
 { day:  7, month: 10, desc: '' },
 { day:  8, month: 10, desc: '' },
 { day:  9, month: 10, desc: '' },
 { day: 10, month: 10, desc: '' },
 { day: 11, month: 10, desc: '' },
 { day: 12, month: 10, desc: '' },
 { day: 13, month: 10, desc: '&check; День игрального кубика' },
 { day: 14, month: 10, desc: '' },
 { day: 15, month: 10, desc: '&check; День мытья рук' },
 { day: 16, month: 10, desc: '' },
 { day: 17, month: 10, desc: '' },
 { day: 18, month: 10, desc: '' },
 { day: 19, month: 10, desc: '' },
 { day: 20, month: 10, desc: '' },
 { day: 21, month: 10, desc: '&hearts; Мамин день' },
 { day: 22, month: 10, desc: '' },
 { day: 23, month: 10, desc: '' },
 { day: 24, month: 10, desc: '' },
 { day: 25, month: 10, desc: '&check; День автомобилиста' },
 { day: 26, month: 10, desc: '' },
 { day: 27, month: 10, desc: '' },
 { day: 28, month: 10, desc: '' },
 { day: 29, month: 10, desc: '' },
 { day: 30, month: 10, desc: '&starf; День памяти жертв политических репрессий' },
 { day: 31, month: 10, desc: '' },
 { day:  1, month: 11, desc: '' },
 { day:  2, month: 11, desc: '' },
 { day:  3, month: 11, desc: '&check; День сэндвича' },
 { day:  4, month: 11, desc: '&equiv; День Ивана Сусанина' },
 { day:  5, month: 11, desc: '' },
 { day:  6, month: 11, desc: '' },
 { day:  7, month: 11, desc: '&starf; День Совка' },
 { day:  8, month: 11, desc: '&ecolon; День Совка, дубль 2' },
 { day:  9, month: 11, desc: '' },
 { day: 10, month: 11, desc: '' },
 { day: 11, month: 11, desc: '' },
 { day: 12, month: 11, desc: '' },
 { day: 13, month: 11, desc: '&check; День доброты' },
 { day: 14, month: 11, desc: '&hearts; ДР бложека' },
 { day: 15, month: 11, desc: '' },
 { day: 16, month: 11, desc: '' },
 { day: 17, month: 11, desc: '' },
 { day: 18, month: 11, desc: '&check; ДР Деда Мороза' },
 { day: 19, month: 11, desc: '' },
 { day: 20, month: 11, desc: '' },
 { day: 21, month: 11, desc: '&check; День зомбоящика' },
 { day: 22, month: 11, desc: '' },
 { day: 23, month: 11, desc: '' },
 { day: 24, month: 11, desc: '' },
 { day: 25, month: 11, desc: '' },
 { day: 26, month: 11, desc: '&hearts; День мобильника' },
 { day: 27, month: 11, desc: '' },
 { day: 28, month: 11, desc: '&hearts; День памяти ужоса' },
 { day: 29, month: 11, desc: '' },
 { day: 30, month: 11, desc: '' },
 { day:  1, month: 12, desc: '' },
 { day:  2, month: 12, desc: '' },
 { day:  3, month: 12, desc: '' },
 { day:  4, month: 12, desc: '&check; День информатики. День писем деду Морозу' },
 { day:  5, month: 12, desc: '' },
 { day:  6, month: 12, desc: '' },
 { day:  7, month: 12, desc: '' },
 { day:  8, month: 12, desc: '' },
 { day:  9, month: 12, desc: '' },
 { day: 10, month: 12, desc: '' },
 { day: 11, month: 12, desc: '' },
 { day: 12, month: 12, desc: '' },
 { day: 13, month: 12, desc: '' },
 { day: 14, month: 12, desc: '' },
 { day: 15, month: 12, desc: '&check; День чая' },
 { day: 16, month: 12, desc: '' },
 { day: 17, month: 12, desc: '' },
 { day: 18, month: 12, desc: '' },
 { day: 19, month: 12, desc: '' },
 { day: 20, month: 12, desc: '' },
 { day: 21, month: 12, desc: '&hearts; Конец света' },
 { day: 22, month: 12, desc: '&hearts; Зимнее солнцестояние, самый короткий день в году' },
 { day: 23, month: 12, desc: '' },
 { day: 24, month: 12, desc: '' },
 { day: 25, month: 12, desc: '&hearts; Начало новогодней суеты' },
 { day: 26, month: 12, desc: '' },
 { day: 27, month: 12, desc: '' },
 { day: 28, month: 12, desc: '' },
 { day: 29, month: 12, desc: '&hearts; Дедушка родился' },
 { day: 30, month: 12, desc: '&starf; День памяти Совка' },
 { day: 31, month: 12, desc: '&ecolon; Предновогодний' }
];
  function today () { //сегодняшняя дата в формате { day: 31, month: 12, year: 2019 }
   let t = new Date();
   let d = t.getDate();
   let m = t.getMonth() + 1;
   let y = t.getFullYear();
   return { day: d, month: m, year: y };
  }
  function diff (d1,m1,d2,m2) { 
   //количество дней от d1.m1 до d2.m2 с учетом перехода через год
   let td = new Date();
   let year = td.getFullYear();
   let y1 = year;
   let y2 = y1;
   if (m1 > m2 || m1 == m2 && d1 > d2) y2++;
   let date1 = new Date (y1, m1-1, d1); 
   let date2 = new Date (y2, m2-1, d2); 
   let d = date2.getTime() - date1.getTime(); 
   return Math.round (d / (1000 * 3600 * 24)); 
  }
  function leapYear(year) {
   return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
  }
  function check (t) { //поиск следующего праздника, вернём его номер в списке или -1
   let nearest = 400;
   let num = -1; 
   for (let i=0; i < Holidays.length; i++) {
    if (Holidays[i].desc.trim()==='' || 
        (Holidays[i].day==29 && Holidays[i].month==2 && !leapYear(t.year))
       ) continue;
    let d = diff(t.day,t.month,Holidays[i].day,Holidays[i].month);
    if (d < nearest) { nearest = d; num = i; }
   }
   return num;
  }
  function strDate (t) { //дата t в формате "31 декабря"
   var monthes = [ '','января','февраля','марта','апреля','мая','июня',
   'июля','августа','сентября','октября','ноября','декабря' ];
   return t.day + ' ' + monthes[t.month];
  }
  let t = today();
  let k = check (t);
  if (k != -1) { //если найдено
   let el = document.getElementById (id);
   let next = { day: Holidays[k].day, month: Holidays[k].month };
   let d = diff (t.day,t.month,next.day,next.month);
   let str = '';
   if (d == 0) str = 'Сегодня празднуем';
   else if (d == 1) str = 'Завтра отмечаем';
   else if (d == 2) str = 'Послезавтра у нас';
   else if (d < 7 ) str = 'Скоро будет праздник';
   else if (d == 7) str = 'Через неделю празднуем';
   else str = 'Следующий праздник';
   el.innerHTML = str + ': ' + strDate(next)+'. '+Holidays[k].desc;
  }
}('holidayId')); //checkHoliday
</script>
<noscript><p>Нужен включённый в браузере Javascript для работы приложения!</p></noscript>

UPD ППТ. Думаю, Вы сами можете добавить перед названиями праздников любые символы Юникода для "категорий", а о способах ввода таких символов в разметку есть вот тут. Я использовал следующие значки "категорий праздника" в этом блоге:

  • ✓ (&check;) - экзотические, не всеобщие праздники, "для галочки";
  • † (&dagger;) - религиозные;
  • ≕ (&ecolon;) - продолжение или преддверие другого праздника;
  • ≡ (&equiv;) - ненастоящие праздники или с негативным для меня оттенком;
  • ♥ (&ecolon;) - личные праздники, с позитивным для меня оттенком;
  • ★ (&starf;) - связанные с СССР/ССРФ.

27.10.2019, 11:33 [2614 просмотров]


теги: программирование список дата javascript время

показать комментарии (1)