|
|||
|
Полезные функции для работы с датой на PHPВывод информации об оставшемся времени на PHPКак вывести кол-во оставшегося времени на PHP, например: "до Нового Года осталось 11 месяцев"? Т.е. не подсчитать кол-во месяцев, а вывести слово "месяц" в правильном падеже? Эту задачу решит функция, опубликованная ниже: function time_left_text($time, $period) { // http://petrenco.com/php.php?txt=122 $arr['s'] = array('секунда', 'секунды', 'секунд'); $arr['m'] = array('минута', 'минуты', 'минут'); $arr['h'] = array('час', 'часа', 'часов'); $arr['d'] = array('день', 'дня', 'дней'); $arr['M'] = array('месяц', 'месяца', 'месяцев'); $arr['Y'] = array('год', 'года', 'лет'); $arr['Y2'] = array('года', 'лет', 'лет'); $time_abs = abs($time); $time_abs = intval(substr($time_abs, -2)); if ($time_abs > 19) $time_abs = intval(substr($time_abs, -1)); $sec_arr[0] = array(2,3,4); $sec_arr[1] = array(0,5,6,7,8,9); if ($time_abs == 1) $ret = $arr[$period][0]; else if (in_array($time_abs, $sec_arr[0])) $ret = $arr[$period][1]; else if (($time_abs >= 5 AND $time_abs <= 20) OR $time_abs == 0) $ret = $arr[$period][2]; return $ret; }
Отличия Y от Y2 в том, что Y применяется только к количественным числительным в именительном падеже: "Моему брату 22 года". Y2 применяется в таких конструкциях: "Моему брату еще нет 22 лет". Подробнее, о правилах русского языка, касающихся применения слов "год" и "лет" можно узнать тут: " На выходе этой функции - строковое значение. Например: echo time_left_text(1535, 'd'); // дней echo time_left_text(251, 's'); // секунда echo time_left_text(22, 'Y'); // года echo time_left_text(22, 'Y2'); // лет Приведение даты к стандарту столбца типа date MySQLКак известно, любые пришедшие от пользователя данные, необходимо скрупулезно проверять на соответствие ожидаемым средствами PHP. Привести дату 20-1-2 к требуемому БД MySQL строковому представлению 0020-01-02 поможет функция sprintf(). echo sprintf('%04d-%02d-%02d', 2012, 2, 30); // 2012-02-30 echo sprintf('%04d-%02d-%02d', 20, 01, 02); // 0020-01-02 На первый взгляд, привести дату к необходимому формату можно и с помощью такой конструкции: echo date('Y-m-d', strtotime('2012-2-30')); // 2012-03-01 echo date('Y-m-d', strtotime('20-1-2')); // 2020-01-02 Но вот только неконтролируемое изменение данных (не существующая дата 30 февраля приводится к ближайшей корректной дате 1 марта и 20 год изменяется на 2020) далеко не всегда приемлемо. Например, если пользователь ввел информацию о том, что он родился 30 февраля, лучше обнаружить ошибку и вывести предупреждение, чем изменить дату рождения на 1 марта. Проверка даты и привидение к формату MySQLФункция $result = check_datetime($datetime, $add, $date_min, $date_max, $out_forma) принимает дату в формате, приближенном к формату MySQL, проверяет ее и возвращает результат: ошибка ($result['err']) и (либо) дату ($result['datetime']) в точном соответствии со стандартами MySQL.
Результат функции - массив, с двумя ключами: [err] и [datetime]:
Проверить, есть ли ошибка (присутствие ключа [err]) в возвращаемом результате, можно с помощью функций: isset($result['err']) или array_key_exist('err', $result). Эта функция требует наличия функции mysqldate_to_mktime($datetime), код которой опубликован на этой странице. // ДАТА - ПРОВЕРКА И ПРИВЕДЕНИЕ К ФОРМАТУ MYSQL // http://petrenco.com/php.php?txt=122 // // $datetime ..... - дата, в формате MySQL гггг[-мм[-дд[ чч[:мм[:сек]]]]] // $add .......... - добавить недостающие части даты и времени. min или max (из 2011 -> min:2011-01-01 00:00:00 или max:2011-12-12 23:59:59) // $date_min ..... - минимально возможная дата, now - теперешняя дата // $date_max ..... - максимально возможная дата, now - теперешняя дата // $out_format ... - выходящий формат даты: datetime или date function check_datetime($datetime, $add = 'min', $date_min = '', $date_max = '', $out_format = 'datetime') { $add = ($add === 'max') ? 'max' : 'min'; if ($out_format === 'datetime') $ret['datetime'] = '0000-00-00 00:00:00'; else $ret['datetime'] = '0000-00-00'; if ($date_min === 'now') $date_min = date("Y-m-d H:i:s"); if ($date_max === 'now') $date_max = date("Y-m-d H:i:s"); if (!$date_min) $date_min_mkt = time() - 47304000; // 730 дней else $date_min_mkt = mysqldate_to_mktime($date_min); if (!$date_max) $date_max_mkt = time() + 47304000; // 730 дней else $date_max_mkt = mysqldate_to_mktime($date_max); $variant = 0; $pattern[1] = '!^[\d]{1,4}[-]{1}[\d]{1,2}[-][\d]{1,2}[ ]{1}[\d]{1,2}[:]{1}[\d]{1,2}[:]{1}[\d]{1,2}$!'; $pattern[2] = '!^[\d]{1,4}[-]{1}[\d]{1,2}[-][\d]{1,2}[ ]{1}[\d]{1,2}[:]{1}[\d]{1,2}$!'; $pattern[3] = '!^[\d]{1,4}[-]{1}[\d]{1,2}[-][\d]{1,2}[ ]{1}[\d]{1,2}$!'; $pattern[4] = '!^[\d]{1,4}[-]{1}[\d]{1,2}[-][\d]{1,2}$!'; $pattern[5] = '!^[\d]{1,4}[-]{1}[\d]{1,2}$!'; $pattern[6] = '!^[\d]{1,4}$!'; $tamplate[1]['min'] = ''; $tamplate[2]['min'] = ':00'; $tamplate[3]['min'] = ':00:00'; $tamplate[4]['min'] = ' 00:00:00'; $tamplate[5]['min'] = '-01 00:00:00'; $tamplate[6]['min'] = '-01-01 00:00:00'; $tamplate[1]['max'] = ''; $tamplate[2]['max'] = ':59'; $tamplate[3]['max'] = ':59:59'; $tamplate[4]['max'] = ' 23:59:59'; $tamplate[5]['max'] = '-31 23:59:59'; $tamplate[6]['max'] = '-12-31 23:59:59'; foreach ($pattern AS $key => $val) { if (preg_match($val, $datetime)) { $variant = $key; } } if ($variant == 0) { $ret['err'] = 'формат даты не верен, (пример даты в необходимом формате: '.date("Y-m-d").')'; return $ret; } $datetime = $datetime.$tamplate[$variant][$add]; $datetime_explode = explode(' ', $datetime); $datetime_explode['date'] = explode('-', $datetime_explode[0]); $datetime_explode['date'][2] = ($variant >= 5 AND $add === 'max') ? cal_days_in_month(CAL_GREGORIAN, $datetime_explode['date'][1], $datetime_explode['date'][0]) : $datetime_explode['date'][2]; $datetime_explode['time'] = explode(':', $datetime_explode[1]); if (!checkdate($datetime_explode['date'][1], $datetime_explode['date'][2], $datetime_explode['date'][0])) $ret['err'] = 'дата введена некорректно, необходимо проверить корректность номера месяца, дня и существование номера дня в выбранном месяце'; if ($datetime_explode['time'][0] > 23 OR $datetime_explode['time'][1] > 59 OR $datetime_explode['time'][2] > 59) { $ret['err'] = 'время указано не верно'; return $ret; } else { if ($out_format === 'datetime') { $datetime = $datetime_explode['date'][0].'-'.$datetime_explode['date'][1].'-'.$datetime_explode['date'][2].' '.$datetime_explode['time'][0].':'.$datetime_explode['time'][1].':'.$datetime_explode['time'][2]; $datetime = sprintf('%04d-%02d-%02d %02d:%02d:%02d', $datetime_explode['date'][0], $datetime_explode['date'][1], $datetime_explode['date'][2], $datetime_explode['time'][0], $datetime_explode['time'][1], $datetime_explode['time'][2]); } else if ($out_format === 'date') { $datetime = $datetime_explode['date'][0].'-'.$datetime_explode['date'][1].'-'.$datetime_explode['date'][2]; $datetime = sprintf('%04d-%02d-%02d', $datetime_explode['date'][0], $datetime_explode['date'][1], $datetime_explode['date'][2]); } $datetime_mkt = mysqldate_to_mktime($datetime); $ret['datetime'] = $datetime; } if ($datetime_mkt < $date_min_mkt) $ret['err'] = 'минимально-допустимая дата: '.date("Y-m-d", $date_min_mkt); if ($datetime_mkt > $date_max_mkt) $ret['err'] = 'максимально-допустимая дата: '.date("Y-m-d", $date_max_mkt); return $ret; } Если допустимый период времени зависит от значения даты на момент запуска функции, например это актуально для лог-файла, в котором хранятся записи за последние 30 дней, то минимальную дату параметра $date_min можно установить следующим образом: $date_min = date('Y-m-d 00:00:00', time() - 60*60*24*30);. Нули в значениях времени позволят избежать введения пользователя в заблуждение, когда в выводимой ошибке о выходе даты за пределы допустимых значений указывается 2012-02-01, а настоящее значение является 2012-02-01 01:15:32 - повторно введя "допустимое" значение 2012-02-01 - пользователь снова увидит ту же ошибку, так как введенное значение преобразуется в 2012-02-01 00:00:00 и будет лежать за пределами минимально-допустимой даты 2012-02-01 01:15:32 (не говоря уже про то, что предел минимально-допустимой даты, зависящей от даты запуска функции, по прошествии времени изменится). Примеры использования функции check_datetime()
$date = date('Y-m'); $result = check_datetime($date); print_r($result); // Array ([datetime] => ГГГГ-ММ-01 00:00:00 ) $result = check_datetime($date, 'max'); print_r($result); // Array ([datetime] => ГГГГ-ММ-31 23:59:59 ) $result = check_datetime('2002-1', 'min', '2002-01-01 01:00:00'); print_r($result); // Array ( [datetime] => 2002-01-01 00:00:00 [err] => минимально-допустимая дата: 2002-01-01 ) $result = check_datetime('2002-1', 'max', '2002-01-01 01:00:00', '2002-01-10 00:00:00'); print_r($result); // Array ( [datetime] => 2002-01-31 23:59:59 [err] => максимально-допустимая дата: 2002-01-10 ) $result = check_datetime('2002-1-2 1:2:3', 'max', '2002-01-01 01:00:00', '2002-01-10 00:00:00', 'date'); print_r($result); // Array ( [datetime] => 2002-01-02 ) $result = check_datetime('2002-2-30 1:2:3', 'max', '2002-01-01 01:00:00', '2345-01-10 00:00:00', 'date'); print_r($result); // Array ( [datetime] => 2002-02-30 [err] => дата введена некорректно, необходимо проверить корректность номера месяца, дня и существование номера дня в выбранном месяце ) Приведение даты из формата MySQL в TimestampФункция mysqldate_to_mktime($date) принимает в качестве параметра дату в формате MySQL datetime (ГГГГ-ММ-ДД чч:мм:сс) или date (ГГГГ-ММ-ДД) и возвращает её значение (строка) в формате timestamp (кол-во секунд с 00:00:00 UTC 1 января, 1970 года). Основное назначение функции - приведение дат в формате MySQL к Timestamp и дальнейшее их сравнение между собой средствами PHP. Например: необходимо узнать, находится ли дата в допустимых пределах. // ПЕРЕВОД ФОРМАТА ДАТЫ ИЗ ФОРМАТА SQL В mktime // $date .... - в формате 0000-00-00 00:00:00 function mysqldate_to_mktime($date) { $date = trim($date); $datetime_explode = explode(" ", $date); $time_explode[0] = 0; $time_explode[1] = 0; $time_explode[2] = 0; if (count($datetime_explode) == 2) { $time_explode = explode(":", $datetime_explode[1]); } $date_explode = explode("-", $datetime_explode[0]); return mktime($time_explode[0], $time_explode[1], $time_explode[2], $date_explode[1], $date_explode[2], $date_explode[0]); } Опубликовано: 2012/02/02
HTML-код ссылки на эту страницу:
<a href="https://petrenco.com/php.php?txt=122" target="_blank">Работа с датой на PHP</a> 31593
Добавить комментарий
|