Заметки о вёрстке сайтов  ·  Александр Шуркаев об HTML, CSS и JavaScript (скрипты, справочники и примеры по сайтостроению)

Как узнать, сколько дней осталось до часа Икс?

22 июня 2002 г.

Как определить, сколько же осталось дней до знаменательного события, учитывая морфологию русского языка?

Недавно для сайта московского кинофестиваля мне необходимо было написать скриптик, который бы определял, сколько же дней осталось до открытия феста 21 июня 2002 года. Это мне было нужно для вывода надписи типа «До открытия кинофестиваля осталось 20 дней».

Разницу между датами (текущей и «часа Икс») найти несложно:

var oToday = new Date(); // текущая дата
var sTime = "June 21, 2002 " + oToday.getHours() + ":" + oToday.getMinutes() + ":" + oToday.getSeconds(); // задаём время с точностью до секунды — это не педантизм, а важная деталь, избавляющая от багов при вычислении разницы между датами
var oDeadLineDate = new Date(sTime); // собственно устанавливаем «час Икс»
var nDaysLeft = oDeadLineDate > oToday ? Math.ceil((oDeadLineDate - oToday) / (1000 * 60 * 60 * 24)) : null; // а тут мы вычисляем, сколько же осталось дней — находим разницу в миллисекундах и переводим её в дни

Итак, мы определили, сколько же осталось дней до знаменательного события. Чудесно.

А теперь в игру вступает великий и могучий русский язык. Дело в том, что слова «осталось … дней» нужно выводить иногда как «остался … день», «осталось … дня» и т. п.

Поэтому необходим следующий код, отслеживающий закономерности:

var sDaysLeft = String(nDaysLeft);
var sDaysText = "дней"; // по умолчанию выводим «дней»
var nDaysLeftLength = sDaysLeft.length;
if (sDaysLeft.charAt(nDaysLeftLength - 2) != "1"){
  if (sDaysLeft.charAt(nDaysLeftLength - 1) == "2" || sDaysLeft.charAt(nDaysLeftLength - 1) == "3" || sDaysLeft.charAt(nDaysLeftLength - 1) == "4"){
    sDaysText = "дня";
  }else if (sDaysLeft.charAt(nDaysLeftLength - 1) == "1"){
    sDaysText = "день";
  }
}

var sLeftText = sDaysText == "день" ? "остался" : "осталось";

Собрав всё воедино и введя для наглядности пару функций, мы получаем следующее:

<script type="text/javascript">
<!--
/*
written by alexander shurkayev <alshur@ya.ru> | http://htmlcssjs.ru
*/

var oToday = new Date();

function getDaysLeft(oDeadLineDate, oToday){
  return oDeadLineDate > oToday ? Math.ceil((oDeadLineDate - oToday) / (1000 * 60 * 60 * 24)) : null;
}

function MkDaysLeft(sDeadLineDate, sDeadLineText){
  var sTime = sDeadLineDate + " " + oToday.getHours() + ":" + oToday.getMinutes() + ":" + oToday.getSeconds();
  var oDeadLineDate = new Date(sTime);
  var nDaysLeft = getDaysLeft(oDeadLineDate, oToday);
  if (nDaysLeft){
    var sDaysLeft = String(nDaysLeft);
    var sDaysText = "дней";
    var nDaysLeftLength = sDaysLeft.length;
    if (sDaysLeft.charAt(nDaysLeftLength - 2) != "1"){
      if (sDaysLeft.charAt(nDaysLeftLength - 1) == "2" || sDaysLeft.charAt(nDaysLeftLength - 1) == "3" || sDaysLeft.charAt(nDaysLeftLength - 1) == "4") sDaysText = "дня";
      else if (sDaysLeft.charAt(nDaysLeftLength - 1) == "1") sDaysText = "день";
    }
    var sLeftText = sDaysText == "день" ? "остался" : "осталось";
    document.write(sDeadLineText + " " + sLeftText + " " + nDaysLeft + " " + sDaysText + ".");
  }else document.write("Кинофестиваль завершился. До новых встреч!");
}

MkDaysLeft("June 21, 2002", "До открытия кинофестиваля");
//-->
</script>

Поскольку начало XXIV кинофестиваля уже свершившийся факт, для примера приведу, сколько дней осталось до моего дня рождения в текущем году.

Код:

MkDaysLeft("October 23, " + oToday.getFullYear(), "До моего дня рождения");

Результат:

Хитовые статьи про разработку сайтов

Рассылка новостей и новых статей

Сообщения будут приходить пару раз в неделю, не чаще

Объявления

LiveInternet