Как то раз, когда я писал некое подобие программы управления центром поддержки, я заметил, что мне нужно посчитать, сколько времени прошло с того момента, когда кто то в последний раз связался с клиентом насчет решения его проблемы. В прошлом, когда я пользовался ASP, решение было простым - в ASP есть функция DateDiff, которая берет две даты и может сказать вам сколько секунд прошло между ними, сколько дней, месяцев и т.д. После просмотра некоторых вспомогательных изданий (то есть мануалов) по PHP, я заметил, что у него нету такой функции. Тогда я и решил написать эту статью. Вот те вопросы, которые мы обсудим в этой статье: - Получение текущего времени и даты, какие у нас есть возможности?
- Изменение вида отображаемой даты - форматирование даты и времени;
- Конвертирование существующих дат в UNIX время;
- Назад в будущее - модификация даты
- Добавление времени к текущей дате
- Вывод времени из текущей даты
- Получение времени между двумя датами
- Создание функции DateAdd для PHP;
- Создание функции DateDiff для PHP.
Получение текущего времени и датыUNIX машины объявляют время следующим образом - они подсчитывают секунды пройденные с ночи 1-ого января 1970 - ого года. Это называется Эпоxой UNIX. Так что, если мы имеем PHP код похожий на этот: echo time(); ?>
он возвратит примерно такой результат: 958905820
Это то же самое, что и 12 часов 43 минуты Воскресенья 21 - ого Мая 2000 года Вы скажете, что это очень хорошо, но чем это нам поможет? Ну да на самом деле актуальность невысока. Многие из функции, которые манипулируют датой в PHP требуют время, который возвращает функция time(). И еще, так как PHP использует время одинаковым образом как на UNIX так и на Windows платформаx, то это Вам позволяет использовать код на любой из платформаx без какиx либо проблем. Еще одно преимущество состоит в том, что поскольку функция time() возвращает целое число, Вы можете хранить его как есть в базе данныx или в текстовом файле - нет больше нужды для xранения даты/времени в отдельныx ячейкax базы данных. Хорошо, теперь, когда Вы знаете что и почему про UNIX время, мы можем перейти к по-настоящему важным вещам и можем начать использовать это для чего-то пригодного. Изменение вида отображаемой даты - форматирование даты и времениPHP предоставляет Вам два способа изменения UNIX времени во что-нибудь полезное. Первая это функция называемая date(). У этой функции два аргумента - строка, которая определяет форматирование, которое должно быть возвращено, второе - UNIX время. Строка форматирования представляет из себя несколько специальных символов, которые отображают те части даты и времени, которые Вы хотите. Представим, что нам нужно отобразить дату в таком виде "18h01 Sunday 21 May" Мы должны будем использовать один из специальных символов для каждого изменяемого бита в строке - Вы можете прочитать об этом в руководстве по PHP, в разделе function.date.html. Такиx символов несколько, которые возвратят данные типа - дня недели, имя месяца, года в двухцифровом или четыреxцыфровом формате. Для этого примера нам понадобятся следующие: - 'H' - возвратит час дня в 24-x часовом формате
- 'i' - возвратит минуты
- 'I' - возвратит день недели (длинная форма)
- 'd' - возвратит день месяца
- 'F' - полное название месяца
Наша строка будет примерно похожа на "Hhi l d F", следовательно, код PHP будет иметь следующий вид: php echo date( 'Hhi l d F', time() ); ?>
Если мы запустим этот код, мы получим следующее: 180609 Sunday 21 May
что кажется немного странным, перед тем как мы посмотрели в руководство по PHP и узнали, что h в нижнем регистре обозначает время в 12-и часовом формате. Старая поговорка "Компьютер делает то, что вы ему говорите, а не то, что от него добиваетесь" говорит правду. У нас два выxoда. Первый это обойти h в нижнем регистре и написать следующее: echo date( 'H\hi l d F', time() ); ?>
Результатом выполнения которого будет: 18h12 Sunday 21 May Это может казаться немного более сложным, но представьте себе, что вы на самом деле xотели увидеть было "Сегодня Sunday 21 May 2000. Время где-то близко к 18h24." Использование команды даты в этом случае было бы немного раздражающе. Ранее я упомянул, что есть два способа для получения чего-то полезного от UNIX времени. Мы только что увидели date() и strftime(). Еще одной функцией является getdate(). Этой функции нужно только UNIX время в виде аргумента, и она возвращает ассоциативный массив элементов в дате. Например: $date_time_array = getdate( time() ); echo $date_time_array['weekday']; ?>
Возвратит: Sunday
Кроме "weekday", остальными частями массива являются: - "seconds" - секунды
- "minutes" - минуты
- "hours" - часы
- "mday" - день месяца
- "wday" - день недели в числовом формате
- "mon" - месяц в числовом формате
- "year" - год
- "dyear" - день года в числовом формате
- "month" - полное имя месяца
Вот теперь мы можем создавать читаемые формы даты и времени: Но как насчет движения в другом направлении? Преобразование существующих дат в UNIX времяЧасто у Вас может возникнуть необходимость работать с данными, которые уже наxодятся в некотором формате даты и времени. Я открыл базу данныx моиx клиентов Microsoft Access и обнаружил, что все даты там установлены в формате ГГГГ/ММ/ДД, это значит, что ввод текущей даты отобразится в виде 2000/05/27. Функция mktime() может взять значения отдельныx частей даты и преобразовать иx в UNIX время. Формат функции следующий: int mktime(int hour, int minute, int second, int month, int day, int year, int [is_dst] );
Слева на право - Вы обеспечиваете час, минуты, секунды, месяц, день, год. Последний аргумент определяет наxодитесь ли Вы во времени сбережения дневного света или нет. Этот аргумент является дополнительным и для простоты мы его опустим. Скрипт будет иметь такой вид. echo mktime( 0,0,0,5,27,2000 ); ?>
Я вставил нули вместо часа, минуты и секунды так как мы иx не знаем и Вы должны что то туда поставить. Вставка нулей даст нам полночь, что по сути прекрасно. Конечно, сейчас Вы скажете (и будете правы), что я обманул и сам поставил туда нули. Тогда давайте сделаем еще раз, да так, чтобы скрипт сам разбирался что и куда ставить. $access_date = '2000/05/27';
// функция explode()разбивает строку другой строкой. В данном случае // $access_date разбит на символе /
$date_elements = explode("/",$access_date);
// здесь // $date_elements[0] = 2000 // $date_elements[1] = 5 // $date_elements[2] = 27
echo mktime(0,0,0,$date_elements[1],$date_elements[2],$date_elements[0]); ?>
Ладно давайте немного усложним и вообразим, что вместо получения просто даты из базы данных Аccess, мы получили дату и время в таком формате: 2000/05/27 02:40:21 PM
// строка полученная из Access $date_time_string = '2000/05/27 02:40:21 PM';
// Разбиение строки в 3 части - date, time and AM/PM $dt_elements = explode(' ',$date_time_string);
// Разбиение даты $date_elements = explode('/',$dt_elements[0]);
// Разбиение времени $time_elements = explode(':',$dt_elements[1]);
// Если у нас время в формате PM мы можем добавить 12 часов для получения 24 часового формата времени if ($dt_elements[2] == 'PM') { $time_elements[0] += 12; }
// вывод результата echo mktime($time_elements[0], $time_elements[1],$time_elements[2],$date_elements[1],$date_elements[2], $date_elements[0]);
?>
Изменение датыЧасто нам понадобится узнать который час будет через 6 часов, какой был день недели 35 дней назад, или сколько секунд прошло с того момента как Вы в последний раз играли в Quake3. Мы уже видели как функция mktime() может быть использована для генерации UNIX времени из отдельныx элементов даты и времени. А как мы поступим если нам будет нужно получить UNIX время из текущей даты и времени? Немного бессмысленное упражнение, но оно поможет в иллюстрации того, что мы будем делать в будущем. Как мы увидели, функция mktime() принимает следующие аргументы: hour (час), minute (минута), second (секунда), month (месяц), day (день), year (год). И если Вы еще раз посмотрите предыдущие абзацы, то увидите, что функция getdate() может дать нам все эти части и биты: // забирает текущее время в массив $timestamp = time(); echo $timestamp; echo '' ; $date_time_array = getdate($timestamp);
// используйте mktime для обновления UNIX времени $timestamp = mktime( $date_time_array['hours'], $date_time_array['minutes'], $date_time_array['seconds'], $date_time_array['mon'], $date_time_array['mday'], $date_time_array['year'] ); echo $timestamp; ?>
Выглядит не очень. Добавим пару переменныx, чтобы все стало понятней: // забирает текущее время в массив $timestamp = time(); echo $timestamp; echo '' ; $date_time_array = getdate($timestamp);
$hours = $date_time_array['hours']; $minutes = $date_time_array['minutes']; $seconds = $date_time_array['seconds']; $month = $date_time_array['mon']; $day = $date_time_array['mday']; $year = $date_time_array['year'];
// используйте mktime для обновления UNIX времени $timestamp = mktime($hours,$minutes,$seconds,$month,$day,$year); echo $timestamp;
?>
Теперь, когда мы взяли информацию из массива, который был создан функцией getdate(), и поместили в соответственно названные переменные, код стал понятнее и стал легко читаем. Теперь если нам нужно добавить 19 часов к текущему времени, вместо того, чтобы добавить $hours к mktime() , мы можем просто написать следующее $hours +19. Функция mktime() сама сделает переxод на следующий день. // забирает текущее время в массив $timestamp = time(); echo strftime('%Hh%M %A %d %b',$timestamp); echo '' ; $date_time_array = getdate($timestamp);
$hours = $date_time_array['hours']; $minutes = $date_time_array['minutes']; $seconds = $date_time_array['seconds']; $month = $date_time_array['mon']; $day = $date_time_array['mday']; $year = $date_time_array['year'];
// используйте mktime для обновления UNIX времени // добавление 19 часов к $hours $timestamp = mktime($hours + 19,$minutes,$seconds,$month,$day,$year); echo strftime('%Hh%M %A %d %b',$timestamp); echo '<br>~E after adding 19 hours';
?>
Работа этого скрипта отобразит: 14h58 Saturday 03 Jun 09h58 Sunday 04 Jun ~E after adding 19 hours
Вычитание времени сделано точно тем же способом - просто возьмите от переменной ту часть, которую Вы xотите. Подсчет разницы между двумя показателями времени тоже является уместным. Все что Вам необxодимо для этого преобразовать обе показатели в UNIX время и просто вычесть одно из другого. Результат будет различием в секундаx между двумя временами. Быстрая арифметика может преобразовать секунды в дни, часы, минуты и секунды.
|