S.Tominoff

Frontend / Backend developer

Работа с DateInterval в PHP

Подробное рассмотрение встроенного PHP класса DateInterval

DateInterval - представляет собой некую продолжительность времени, которую мы можем использовать при сдвигах даты.

 

К примеру

В обычном разговоре, вы ведь вряд-ли скажете "я буду у тебя 2 января 2015 года в 7:38"? 

Естественно, вместо этого намного уместнее будет сказать – "я буду у тебя через 10 минут".

Но как объяснить интерпретатору PHP, что значит эта заветная фраза "через 10 минут"?

 

Именно для таких ситуаций и используется DateInterval.

 

Рассмотрим элементарный пример использования:

// текущая дата:
$dateTime = new DateTime;
// интервал с размером сдвига в 1 день
$dateInterval = new DateInterval('P1D');
// получаем завтрашнее число
$tomorrow = $dateTime->add($dateInterval)->format("d");
echo "послезавтра будет " . $tomorrow . " число"

 

 

 

Конструктор DateInterval и Iso 8601

 

Вся магия заключается в строке переданной в конструктор - 'P1D'. Что это за P1D? Согласно стандарту ISO 8601-2004 (или ГОСТ ИСО 8601-2001), P и D являются знаками, использующимся в качестве указателей (designator) (п. 3.4.3 и 4.4 версий стандартов соответственно). Для использования DateInterval понадобится запомнить всего лишь несколько указателей:

 

УказательРасшифровкаОписание
PPeriodНачало периода времени
YYearГод
MMonthМесяц
DDayДень
TTimeНачало представления объекта времени
HHourЧасы
MMinuteМинуты
SSecundeСекунды

 

Единственный обязательный указатель - P, все остальные опциональны.

 

Посмотрим на пару примеров:

// Период времени = 1 день
$p = "P1D";
// Период времени = 8 часов
$p = "PT8H";
// Период времени = 4 дня 8 часов 12 минут 32 секунды
$p = "P4DT8H12M32S";

 

Любой другой период можно составить по аналогии P<%Y%M%D><T><%H%M%S>

 

 

Анатомия класса DateInterval

 

DateInterval содержит в себе только конструктор и два открытых метода.

  1. static createFromDateString - создает объект DateInterval из строки относительного формата времени
  2. format - форматирует интервал для вывода

 

Также у класса есть открытые члены:

  1. - количество лет
  2. m - количество месяцев
  3. d - количество дней
  4. h - количество часов
  5. i - количество минут
  6. s - количество секунд

Используя их можно динамически управлять периодом.

 

Давайте представим, что мы реализуем систему подачи заявок на предзаказ, причем анонимные посетители могут оформить предзаказ только за неделю до появления товара, а зарегистрированные, за три недели.

 

Предположим что наша система разрабатывается на Yii, в коде это можно было бы выразить так:

 

// ... code
$di = new DateInterval("P7D");
$date_from = new DateTime();
if(!Yii::app()->user->isGuest)
    $di->d += 14;
$date_to = (new DateTime)->add($di);
// получаем все товары с датой выхода между сегодня и <сегодня + % дней>
$criteria->addBetweenCondition('release_date', $date_from, $date_to);
// ... code

 

Таким образом, если выполняется условие !Yii::app()->user->isGuest, т.е. пользователь зарегистрирован, интервал будет увеличен на 14 дней, соответственно зарегистрированный пользователь увидит товары с предзаказом за 21 день перед появлением.