За последние 24 часа нас посетили 20958 программистов и 1131 робот. Сейчас ищут 357 программистов ...

универсальный is_valid_date

Тема в разделе "Регулярные выражения", создана пользователем Koc, 5 ноя 2009.

  1. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    на php.net в комментах нашел такое:
    PHP:
    1. <?php
    2. /**
    3.  * Checks date if matches given format and validity of the date.
    4.  * Examples:
    5.  * <code>
    6.  * is_date('22.22.2222', 'mm.dd.yyyy'); // returns false
    7.  * is_date('11/30/2008', 'mm/dd/yyyy'); // returns true
    8.  * is_date('30-01-2008', 'dd-mm-yyyy'); // returns true
    9.  * is_date('2008 01 30', 'yyyy mm dd'); // returns true
    10.  * </code>
    11.  * @param string $value the variable being evaluated.
    12.  * @param string $format Format of the date. Any combination of <i>mm<i>, <i>dd<i>, <i>yyyy<i>
    13.  * with single character separator between.
    14.  */
    15. function is_valid_date($value, $format = 'dd.mm.yyyy'){
    16.     if(strlen($value) >= 6 && strlen($format) == 10){
    17.        
    18.         // find separator. Remove all other characters from $format
    19.         $separator_only = str_replace(array('m','d','y'),'', $format);
    20.         $separator = $separator_only[0]; // separator is first character
    21.        
    22.         if($separator && strlen($separator_only) == 2){
    23.             // make regex
    24.             $regexp = str_replace('mm', '(0?[1-9]|1[0-2])', $format);
    25.             $regexp = str_replace('dd', '(0?[1-9]|[1-2][0-9]|3[0-1])', $regexp);
    26.             $regexp = str_replace('yyyy', '(19|20)?[0-9][0-9]', $regexp);
    27.             $regexp = str_replace($separator, "\\" . $separator, $regexp);
    28.             if($regexp != $value && preg_match('/'.$regexp.'\z/', $value)){
    29.  
    30.                 // check date
    31.                 $arr=explode($separator,$value);
    32.                 $day=$arr[0];
    33.                 $month=$arr[1];
    34.                 $year=$arr[2];
    35.                 if(@checkdate($month, $day, $year))
    36.                     return true;
    37.             }
    38.         }
    39.     }
    40.     return false;
    41. }
    вопрос такой: может кто-нить поделится универсальной ф-цией проверки даты? входные параметры: проверяемая строка, формат (как в оригинальной ф-ции date)?
     
  2. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Даже человек не всегда в силах различить дату.
    Дам пример:
    09.06.11 .. нет, это не девятое июня 2011 года - нет, это 6 ноября 2009 года.
    Поэтомы сверху описаны универсальнейшие варианты.
     
  3. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    ну вот у меня в проекте разрешено записывать время отдыха в отеле в формате мм.гггг. Ну и нужно как-то проверить то, что прислал пользователь.
    А при регистрации он задает дату рождения дд.мм.гг
    А при редактировании новости записывается дата в формате MySQL DateTime..

    и так далее
     
  4. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
  5. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    А я всё в timestamp пишу и через mktime прогоняю.
    Удобно форматировать вывод с помощью date - это раз, никаких проблем со стандартами - два.
    Естественно, поскольку у нас ограничение есть - 1970г., то даты рождения пишем как они есть.
     
  6. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
  7. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    нашел
    http://grezz.ru/?p=123
    и
    PHP:
    1. <?php
    2. /*******************************************************
    3.  * Simple function to take in a date format and return array of associated
    4.  * formats for each date element
    5.  *
    6.  * @return array
    7.  * @param string $strFormat
    8.  *
    9.  * Example: Y/m/d g:i:s becomes
    10.  * Array
    11.  * (
    12.  *     [year] => Y
    13.  *     [month] => m
    14.  *     [day] => d
    15.  *     [hour] => g
    16.  *     [minute] => i
    17.  *     [second] => s
    18.  * )
    19.  *
    20.  *  This function is needed for  PHP < 5.3.0
    21.  ********************************************************/
    22. function date_parse_from_format($stFormat, $stData)
    23. {
    24.     $aDataRet = array();
    25.     $aPieces = split('[:/.\ \-]', $stFormat);
    26.     $aDatePart = split('[:/.\ \-]', $stData);
    27.     foreach ($aPieces as $key=>$chPiece) {
    28.         switch ($chPiece) {
    29.             case 'd':
    30.             case 'j':
    31.                 $aDataRet['day'] = $aDatePart[$key];
    32.                 break;
    33.                
    34.             case 'F':
    35.             case 'M':
    36.             case 'm':
    37.             case 'n':
    38.                 $aDataRet['month'] = $aDatePart[$key];
    39.                 break;
    40.                
    41.             case 'o':
    42.             case 'Y':
    43.             case 'y':
    44.                 $aDataRet['year'] = $aDatePart[$key];
    45.                 break;
    46.            
    47.             case 'g':
    48.             case 'G':
    49.             case 'h':
    50.             case 'H':
    51.                 $aDataRet['hour'] = $aDatePart[$key];
    52.                 break;  
    53.                
    54.             case 'i':
    55.                 $aDataRet['minute'] = $aDatePart[$key];
    56.                 break;
    57.                
    58.             case 's':
    59.                 $aDataRet['second'] = $aDatePart[$key];
    60.                 break;          
    61.         }
    62.        
    63.     }
    64.     return $aDataRet;
    65. }
    66.  
    на работоспособность не проверял. Обе они не возвращают ошибок и варнингов(
     
  8. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    раньше тоже так делал. Сейчас забил, ставлю поля Date, DateTime.
     
  9. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Я наоборот недавно перешёл на другой способ.
     
  10. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    имеем такой быдлокод http://pastebin.mozilla-russia.org/102482

    isValidDate('10.2002', 'm.Y') - false.
    в момент сравнения $date и change_date_format($date, $format, $format); change_date_format возвращает 09.2002
     
  11. TheShock

    TheShock Активный пользователь

    С нами с:
    30 май 2009
    Сообщения:
    1.255
    Симпатии:
    0
    Адрес:
    Київ
    Делаю так же, как Apple. Одно "но". Мы ограничены не 1970 :)
    Код (Text):
    1. shock@shock:~$ php -r 'echo date("Y", -2000000000);'
    2. 1906
     
  12. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.340
    Симпатии:
    44
    Код (Text):
    1. if (! ($timestamp = strtotime($input_date))
    2.    return false;
    3. $formated_date = date($format, $timestamp);
    4. if ($input_date != $formated_date)
    5.   return false;
    6. return true;
    =)
     
  13. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    MiksIr
    это к моему коду или не?
     
  14. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Эммм ... а разве в MySQL не 1970?
     
  15. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.340
    Симпатии:
    44
    Koc, ну да, если уж очень хочется, что бы дата была в одном формате.
    Хотя по мне, так просто использовать strtotime достаточно. А для пользователей нужно нормальныое UI, что бы он не морочился форматом, а на входе в валидаторе банальный регексп.
     
  16. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    нормальный UI будет. Но мне все равно нужно проверять что от него приходит.

    Каким образом твой код обработает 14:59? (без одной минуты 3 часа)
     
  17. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.340
    Симпатии:
    44
    А самому проверить?
    Код (Text):
    1. php -r ' $time = strtotime("14:59"); print date("r", $time); '
    Thu, 05 Nov 2009 14:59:00 +0300
     
  18. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    блин. Ну я все равно помню, что это хуже чем date_parse_from_format. В зависимости от локали она по-разному работает. Помню, что на локальной машине все нормально работало, а на дев-сервере бочинило.