Робота з датою на PHP
Виведення інформації про час, що залишився на PHP
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 ] ;
- $ time - величина часу, ціле число;
- $period - назва періоду часу: s - секунда, m - хвилина, d - день, M - місяць, Y - рік, Y2 - рік у трохи іншому форматі.
Відмінності Y від Y2 в тому, що Y застосовується лише до кількісних чисельних у називному відмінку: "Моєму братові 22 роки". Y2 застосовується в таких конструкціях: "Моєму братові ще немає 22 років". Докладніше про правила української мови щодо застосування слів "рік" і "років" можна дізнатися тут: "Використання слів "років" і "рік"". Ці ж правила, застосовні й інших назв величин часу: секунда, хвилина та інших., але у функції використовуються найчастішезустрічаються відміни.
На виході цієї функції – рядкове значення. Наприклад:
Приведення дати до стандарту стовпця типу date MySQL
Як відомо, будь-які дані, що прийшли від користувача, необхідно скрупульозно перевіряти на відповідність очікуваним засобами PHP. Привести дату 20-1-2 до необхідного БД MySQL строкового подання 0020-01-02 допоможе функція sprintf().
На перший погляд, привести дату до необхідного формату можна за допомогою такої конструкції:
Перевірка дати та привид до формату MySQL
Функція $result = check_datetime ( $datetime , $add , $date_min , $date_max , $out_forma ) приймає дату у форматі, наближеному до формату MySQL, перевіряє її та повертає результат: помилка ( $result [ 'err' ] ) і (або ) дату ( $result [ 'datetime' ] ) у точній відповідності до стандартів MySQL.
- $datetime - дату в функцію можна передавати в повному (2012-03-02 20:50:01) або скороченому форматі (2012-03). Мінімальне значення - рік, що складається з 1 цифри. Дата і час можуть коректно перевірятися і без провідних нулів, наприклад, перевіривши таку дату: 1001-3-2 2:3:1, на виході функції вона виглядатиме так: 1001-03-02 02-03-01.
- $add - доповнити дату максимальними чи мінімальними значеннями. Допустимі значення: min (за замовчуванням) або max. Наприклад, передавши дату 2012-02 та встановивши $add = max, на виході функція поверне 2012-02-29 23:59:59. При $add = min дата 2012-02 перетворюється на 2012-02-01 00:00:00. Цей параметр дуже зручно використовувати, коли потрібно запросити діапазон дат, наприклад, від 2010 до 2012 року. У цьому випадку для перевірки поля "від" встановлюється $add = min, а для "до" - $add = max, в результаті чого на виході функції будуть такі дати: для 2010 р.: 2010-01-01 00: 00:00; для 2012р.:2012-12-31 23:59:59.
- $date_min і $date_max - мінімально та максимально допустимі дати у повному MySQL форматі (наприклад, 2012-03-02 20:50:01). Також, як значення можна встановити ключове слово now, у цьому випадку буде використана поточна дата. Якщо дата, надіслана на перевірку, буде менше або більше дат, зазначених у цих параметрах, функція поверне помилку. Якщо ці параметри не вказані - мінімальна та максимальна дати будуть, відповідно, -730 та 730 днів від дати на момент перевірки. В офіційній документації до MySQL сказано, що для стовпця таблиці з типом datetime, допустимими є значення від 1000-00-00 00:00:00 до 9999-12-12 23:59:59 - цю інформацію слід взяти до уваги при встановленні граничних порогів дат.
- $out_format - формат дати, що повертається функцією: datetime (РРРР-ММ-ДД чч:мм:сс) або date (РРРР-ММ-ДД).
Результат функції - масив, з двома ключами: [err] та [datetime]:
- [datetime] - дата у форматі MySQL date чи datetime, залежно від встановленої змінної $out_format. Дата повертається завжди, навіть у разі помилки (якщо дата, що перевіряється, некоректна, повертається дата 0000-00-00 00:00:00).
- [err] – текстове повідомлення про помилку.
Перевірити, чи є помилка (присутність ключа [err]) у результаті, що повертається, можна за допомогою функцій: isset ( $result [ 'err' ] ) або array_key_exist ( 'err' , $result ) .
// ДАТА - ПЕРЕВІРКА І ПРИВЕДЕННЯ ДО ФОРМАТУ 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][-][\d][-][\d][ ][\d][:][\d][:][\d] $! ; $pattern [ 2 ] = '!^[\d][-][\d][-][\d][ ][\d][:][\d]$!' ; $pattern [ 3 ] = '!^[\d][-][\d][-][\d][ ][\d]$!' ; $pattern [ 4 ] = '!^[\d][-][\d][-][\d]$!' ; $pattern [ 5 ] = '!^[\d][-][\d]$!' ; $pattern [ 6 ] = '!^[\d]$!' ; $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 (! ' ] = 'дата введена некоректно, необхідно перевірити коректність номера місяця, дня та існування номера дня у вибраному місяці'; 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; >
Якщо допустимий період часу залежить від значення дати на момент запуску функції, наприклад, це актуально для лог-файлу, в якому зберігаються записи за останні 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 (не говорячи вже про те, що межа мінімально-допустимої дати, яка залежить від дати запуску функції, з часом зміниться).
$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-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
Основне призначення функції – приведення дат у форматі MySQL до Timestamp та подальше їх порівняння між собою засобами PHP. Наприклад: потрібно дізнатися, чи знаходиться дата в допустимих межах.