[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: "Умная" дата
Timok
На написание этой функции натолкнула заметка "Хороший интерфейс". Смысл, вкратце: заменяем 5 полей ввода даты (час, минута, день, месяц, год) одним полем с "почти" произвольным форматов вводимой даты. Т.е. скрипт должен разбирать строки типа "вчера, в 8 часов вечера", "в понедельник утром", "сегодня в 3:00 ночи" и т.п.

код получился громоздким. Функция понимает названия месяцев, дни недели, слова "вчера", "сегодня" и "завтра" (можно будет усовершенствовать - добавить приставки "поза" и "после"), слова "утром","днём","вечером", ночью". Разбирает утреннее и вечернее время (т.е. 8 вечера - 20:00). Кому интересно попробуйте повводите дату по-разному.

Код
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
<head profile="http://gmpg.org/xfn/11">
<title>Дата-робот </title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
html, body{
font-family:Georgia,"Times New Roman",serif;
font-size:62.5%/1.4;
color:#333;
}
ul{
list-style:none;
}
#datetime, #result {
border:1px solid #ccc;
width:500px;
height:35px;
font-family:Georgia, "Times New Roman", serif;
font-size:1.5em;
padding:5px;
margin:5px;
}
#result {
background:#eee;
color:#333;
text-align:right;
}
</style>
</head>
<body>
<p>Примеры:<br />
— «вчера я проснулся рано утром»<br />
— «опубликовать завтра к 7 часам вечера»<br />
—  или просто «15:00, 8 марта 2005»<br />
</p>
<div>
<input id="datetime" type="text" value="Вводить здесь"
onkeypress="dateParser('datetime','result');"
onblur="dateParser('datetime','result');"
onmouseover="dateParser('datetime','result');" />
<div id="result">Смотреть сюда</div>
</div>

<script type="text/javascript">
function dateParser(input_id, output) {
  var strTime = document.getElementById(input_id).value.toLowerCase();
  if (! strTime) return false;
  var current = new Date();
  var minute, hour, day, month, year;
  var abstract;
  var regExp, result;  
  strTime = strTime.replace(/[\s]{2,}/, " ");  
  // Сначала определяем дату (число и месяц)
  // Сначала ищем слова "вчера", "сегодня", "завтра", а так же "после"
  regExp = /вчера|сегодня|завтра/i;
  arResults = regExp.exec(strTime);
  if (arResults) {
    abstract = arResults[0];
    month = current.getMonth() + 1;
    year = current.getFullYear()
    switch (abstract) {
      case "вчера":
        day = current.getDate() - 1;
        if (day == 0) {
        // если сегодня - 1 число месяце:
          if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
          // в предыдущем месяце 30 дней
            day = 30;
          } else if (month == 4 || month == 6 || month == 9 || month == 11) {
          // в предыдущем месяце 31 дней
            day = 31;
          } else if (month == 2) {
           // предыдущий месяц - февраль
            if (year % 4 == 0) {
              day = 29;
            } else {
              day = 28;
            }
          }
          --month;
          if (month == 0) {
            month = 12;
            --year;
          }
        }
        break;
      case "сегодня":
        day = current.getDate();
        break;
      case "завтра":
        day = current.getDate() + 1;
        // если сегодня - последний день месяца
        if (day == 32) {
          day = 1;
          ++month;
        } else if (day == 31) {
          if (month == 4 || day == 6 || day == 9 || day == 11) {
            day = 1;
            ++month;
          }
        } else if (day == 29 || day == 28) {
          if (month == 2) {
            day = 1;
            month = 3;
          }
        }
        break;
    }
  } else {
    regExp = /понедельник|вторник|сред|четверг|пятниц|суббот|воскресен/i;
    arResults = regExp.exec(strTime);
    if (arResults) {
      abstract = arResults[0];
      dayOfWeek = current.getDay();
      if (dayOfWeek == 0) dayOfWeek = 7;
      switch (abstract) {
        case "понедельник":
          abstract = 1;
          break;
        case "вторник":
          abstract = 2;
          break;
        case "сред":
          abstract = 3;
          break;
        case "четверг":
          abstract = 4;
          break;
        case "пятниц":
          abstract = 5;
          break;
        case "суббот":
          abstract = 6;
          break;
        case "воскресени":
          abstract = 7;
          break;
      }
      year = current.getFullYear();
      month = current.getMonth() + 1;    
      day = current.getDate() + (abstract - dayOfWeek);
      if (day < 1) {
        --month;
        if (month == 0) month = 12;
        if (month == 4 || month == 6 || month == 9 || month == 11) {
          day = 30 + day;
        } else if (month == 2) {
          if (year % 4 == 0) {
            day = 29 + day;
          } else {
            day = 28 + day;
          }
        } else {
          day = 31 + day;
          if (month == 12) {
            --year;
          }
        }
      }
    } else {
      // Число может состоять из 1-2 цифр, перед ним должен быть или хотя бы 1
      // проблельный символ, или начало строки. После числа следует месяц. Между
      // ними может быть любое количество пробельных символов (или ни одного).
      regExp = /(^|\s+)([0-9]|[0-2][0-9]|3[0-1])[\.\-\/\s](1[1,2]|0?[\d]|янв|фев|мар|апр|ма|июн|июл|авг|сен|окт|ноя|дек)/i;
      arResults = regExp.exec(strTime);
      if (arResults) {
        day = arResults[2];
        month = arResults[3];      
        // Год должен состоять из 4-х цифр, перед ним должен быть пробел или начало
        // строки, после - пробел или конец строки.
        regExp = /(^|\s+)([\d]{4})(\s+|$)/;
        arResults = regExp.exec(strTime);
        if (arResults) year = arResults[2];        
        switch (month) {
          case "янв": month =  1; break;
          case "фев": month =  2; break;
          case "мар": month =  3; break;
          case "апр": month =  4; break;
          case "ма" : month =  5; break;
          case "июн": month =  6; break;
          case "июл": month =  7; break;
          case "авг": month =  8; break;
          case "сен": month =  9; break;
          case "окт": month = 10; break;
          case "ноя": month = 11; break;
          case "дек": month = 12; break;
        }
      }
    }  
  }
  // отдельно определим год
  regExp = /19|20[0-9]{2}/;
  arResults = regExp.exec(strTime);
  if (arResults) {
    year = arResults[0];
  } else {
    year = current.getFullYear();
  }
  // Теперь определим время
  regExp = /час[|а|ов|у|ам|е]+/i;
  strTime = strTime.replace(regExp, ':00');
  regExp = /(([0-9]|[0-1|\s][0-9])|(2[0-3]))[\s\:]+([0-5][0-9]|час[\w]{0,2})[\s]*((.*)|(дня)|(вечера)|(ночи))/i;
  arResults = regExp.exec(strTime);
  if (arResults) {
    hour = parseInt(arResults[1]);  
    regExp = /час[\w]{0,2}/;
    minute = (regExp.test(arResults[4])) ? '00' : arResults[4];  
    regExp = /[\s]*(дня|вечера|ночи)[\s]*/i;
    arResults = regExp.exec(arResults[5]);
    if (arResults) {
      abstract = arResults[1];
      switch (abstract) {
        case 'дня':
          if (hour >= 1 && hour <= 5) hour += 12;
          break;
        case 'вечера':
          if (hour >= 5 && hour <= 12) hour += 12;
          break;
        case 'ночи':
          if (hour == 11 || hour == 12) hour += 12;
          break;
      }
    }
  } else {
    regExp = /утр|дн[е,ё]м|вечер|ноч/i;
    arResults = regExp.exec(strTime);
    if (arResults) {
      minute = '00';
      switch (arResults[0]) {
        case "утр": hour = '06'; break;          
        case ("днем" || "днём"): hour = '12';
        case "вечер": hour = '18'; break
        default: hour = '00';
      }
    }
  }
  if (! year) year = current.getFullYear();
  if (! month) month = current.getMonth() + 1;
  if (! day) day = current.getDate();
  if (! hour) hour = current.getHours();
  if (! minute) minute = current.getMinutes();    
  var result = hour + ":" + minute + ", " + day + "/" + month + "/" + year;
  document.getElementById(output).innerHTML = result;
  return result;
}
</script>
</body>
</html>
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.