Yandex Metrika
sanches.free 24 просмотра

Дата и время в Bitrix D7: Type\Date, Type\DateTime, культура сайта и часовые пояса

Зачем отдельные типы

В D7 для полей ORM, настроек культуры и почти всего, что связано с «датой без времени» и «датой со временем», используют \Bitrix\Main\Type\Date и \Bitrix\Main\Type\DateTime. Второй расширяет первый: у него есть часы, минуты и секунды. Они знают о форматах, заданных в региональных настройках сайта, и дают единообразный вывод в шаблонах и админке.

Создание из строки, метки времени и PHP

Одноаргументный конструктор интерпретирует строку в формате текущего сайта (как правило, это комбинация FORMAT_DATE / FORMAT_DATETIME из культуры). Вторым параметром можно передать свой шаблон в стилю PHP (Y-m-d H:i:s и т. п.). Для календарных дат без времени берут Date. Неверный формат безопаснее ловить через try/catch вокруг конструктора: ядро бросает \Bitrix\Main\SystemException.

use Bitrix\Main\SystemException;
use Bitrix\Main\Type\Date;
use Bitrix\Main\Type\DateTime;

$postedAt = new DateTime('14.06.2018 02:20:00');
$loggedAt = new DateTime('2018-06-14 02:20:00', 'Y-m-d H:i:s');
$onlyDay = new Date('14.06.2018');

try {
    $parsed = new DateTime($incoming, 'Y-m-d H:i:s');
} catch (SystemException $e) {
    $errors[] = 'Некорректная дата';
}

$msc = new \DateTimeZone('Europe/Moscow');
$tzAware = new DateTime('2018-06-14 02:20:00', 'Y-m-d H:i:s', $msc);

$fromUnix = DateTime::createFromTimestamp(time());
$fromPhp = DateTime::createFromPhp(new \DateTime('2018-01-01'));

// Разбор «человеческих» фраз локали (если поддерживается версией):
$fuzzyMorning = Date::createFromText('вчерашнее утро');

Форматы культуры и вывод

Активный формат даты/времени для сайта удобно смотреть статическими методами DateTime::getFormat() и Date::getFormat() без аргумента. Для произвольной культуры тот же метод принимает экземпляр \Bitrix\Main\Context\Culture и возвращает строку формата уже в нотации PHP.

Метод toString() даёт представление в формате сайта; format('…') — в любом шаблоне; getTimestamp() — целое UNIX-время. Перед выводом в шаблоне имеет смысл убедиться, что переменная действительно экземпляр одного из типов:

use Bitrix\Main\Context\Culture;
use Bitrix\Main\Localization\CultureTable;
use Bitrix\Main\SiteTable;
use Bitrix\Main\Type\DateTime;

$siteFormat = DateTime::getFormat();

if ($value instanceof DateTime || $value instanceof \Bitrix\Main\Type\Date) {
    echo $value->toString();
}

// Формат не текущего сайта (пример: s4)
$q = SiteTable::getList([
    'filter' => ['=LID' => 's4'],
    'select' => ['CULTURE_ID'],
    'limit' => 1,
]);
if ($row = $q->fetch()) {
    $cultureRow = CultureTable::getById($row['CULTURE_ID'])->fetch();
    $foreignCulture = new Culture($cultureRow);
    echo $value->toString($foreignCulture);
}

$custom = new Culture([
    'FORMAT_DATE' => 'MM/DD/YYYY',
    'FORMAT_DATETIME' => 'MM/DD/YYYY HH:MI:SS',
    'FORMAT_NAME' => '#NAME# #LAST_NAME#',
    'CHARSET' => 'UTF-8',
    'DIRECTION' => 'Y',
    'WEEK_START' => 0,
]);
echo $value->toString($custom);

// Форматы в нотации Битрикс vs PHP:
// $custom->getDateFormat(), $custom->getDateTimeFormat()
// \Bitrix\Main\Type\Date::getFormat($custom)

Пользовательское время и проверки

Когда дата введена «как видит пользователь», а хранить нужно в серверной логике, помогают DateTime::createFromUserTime() и toUserTime() для обратного отображения. Шаблон полей из настроек культуры иногда нужно скормить чистому PHP: DateTime::convertFormatToPhp() переводит синтаксис Битрикс в символы date(). Быстрая валидация без исключений — DateTime::isCorrect().

use Bitrix\Main\Type\DateTime;

$entered = DateTime::createFromUserTime('14.06.2018 02:20:00');
echo $entered->toUserTime();

$phpPattern = DateTime::convertFormatToPhp('YYYY-MM-DD HH-MI-SS'); // например "Y-m-d H-i-s"

$ok = DateTime::isCorrect('2018-06-14 02:20:00', 'Y-m-d H:i:s');

Сдвиги, интервалы и часовые пояса

add() мутабелен: для цепочки экспериментов клонируйте объект. Поддерживаются читаемые строки («1 year + 3 months - 5 seconds») и компактная запись интервалов. Работа с поясами идёт через стандартный \DateTimeZone; сброс к настройке по умолчанию — setDefaultTimeZone().

use Bitrix\Main\Type\DateTime;

$invoiceDue = new DateTime('01.06.2026 12:00:00');
$reminder = clone $invoiceDue;
$reminder->add('1 month - 2 days');

$billing = clone $invoiceDue;
$billing->add('1YT1200S'); // DateInterval-стиль

$prefs = new \DateTimeZone('Europe/Moscow');
echo $invoiceDue->getTimeZone()->getName();
$invoiceDue->setTimeZone($prefs);
$invoiceDue->setDefaultTimeZone();

На что смотреть в продакшене

  • Не смешивайте сырые строки из формы и объект ORM без приведения к Type\DateTime — иначе при сохранении сущность получит не тот тип.
  • Учитывайте, что вывод через toString() зависит от контекста культуры; для API и интеграций чаще фиксируют format('Y-m-d\TH:i:sP') или хранят timestamp.
  • После нескольких add() убедитесь, что не мутируете объект, который ещё держит фреймворк внутри выборки.

Кратко

Date и DateTime закрывают парсинг, форматирование, сравнение с культурой сайта, пользовательскими настройками и часовыми поясами; для интеграций пригодятся createFromTimestamp, createFromPhp, convertFormatToPhp и isCorrect.

Не хотите копаться сами?

Починю за 1-3 дня. Без предоплаты — оплата по результату.

15+ лет опыта с 1С-Битрикс · Без предоплаты · 7 дней гарантии