Дата и время в 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 дней гарантии