Работа с датами и временем в PHP может быть сложной из-за форматов, часовых поясов и ручных манипуляций.
В старом ядре Битрикс для этого использовался набор функций (MakeTimeStamp, FormatDate, ConvertDateTime), которые требовали внимательности и часто приводили к ошибкам.
В ядре D7 для решения этих проблем введены специальные классы \Bitrix\Main\Type\DateTime и \Bitrix\Main\Type\Date.
Ключевые преимущества D7-объектов дат
- Объектно-ориентированный подход: Вместо набора глобальных функций вы работаете с объектами, что делает код чище и понятнее.
- Учет часовых поясов: Объекты DateTime автоматически работают с учетом настроек часовых поясов сайта и пользователя.
- Интеграция с ORM: Поля DateField и DatetimeField в D7 ORM «понимают» эти объекты, автоматически конвертируя их в нужный формат для базы данных.
- Удобные методы: Предоставляют богатый API для форматирования, сравнения и арифметических операций с датами.
1. Создание объекта даты
\Bitrix\Main\Type\DateTime (Дата и время)
use Bitrix\Main\Type\DateTime;
// 1. Создание из строки (формат берется из настроек сайта)
// Например, если формат сайта 'd.m.Y H:i:s'
$dateFromRequest = new DateTime('26.10.2024 15:30:00');
// 2. Из строки с явным указанием формата PHP
$dateFromDb = new DateTime('2024-10-26 15:30:00', 'Y-m-d H:i:s');
// 3. Из Unix timestamp
$dateFromTimestamp = DateTime::createFromTimestamp(time());
// 4. Пустой конструктор (текущее время)
$now = new DateTime();
\Bitrix\Main\Type\Date (Только дата)
Работает аналогично, но оперирует только датой, игнорируя время.
use Bitrix\Main\Type\Date;
$date = new Date('26.10.2024', 'd.m.Y');
Безопасная работа с пользовательским вводом:
Никогда не доверяйте данным из $_POST или $_GET. Используйте статические методы для безопасной проверки и создания.
// Проверка корректности строки
if (Date::isCorrect('26.10.2024')) {
// дата корректна
}
// Попытка создать объект (вернет null в случае ошибки)
$date = DateTime::tryParse('неверная дата', 'd.m.Y H:i:s');
if ($date === null) {
echo "Неверный формат даты";
}
2. Форматирование и получение данных
$now = new DateTime();
// Формат из настроек культуры текущего сайта (например, 'DD.MM.YYYY HH:MI:SS')
echo $now->toString();
// Кастомный PHP-формат
echo $now->format('Y-m-d'); // 2024-10-26
// Получение Unix timestamp
echo $now->getTimestamp();
3. Арифметические операции и модификация
Методы add() и modify() принимают строку в формате, понятном для strtotime или DateInterval.
Важно: Эти методы изменяют текущий объект и возвращают на него же ссылку ($this), что позволяет строить цепочки вызовов.
$date = new DateTime('2024-10-26 15:30:00', 'Y-m-d H:i:s');
// Прибавить 1 день и 2 часа
$date->add("+1 day 2 hours");
echo $date->format('Y-m-d H:i:s'); // 2024-10-27 17:30:00
// Можно строить цепочки
$date->add("-1 month")->modify("first day of this month");
echo $date->format('Y-m-d H:i:s'); // 2024-09-01 17:30:00
// Чтобы не изменять исходный объект, его нужно клонировать
$originalDate = new DateTime();
$newDate = (clone $originalDate)->add("P1M"); // Прибавить 1 месяц
4. Работа с часовыми поясами (Timezones)
Это одно из главных преимуществ DateTime. Система автоматически управляет конвертацией между временем сервера и временем пользователя.
- toUserTime(): Конвертирует время объекта (которое считается серверным) во время текущего пользователя. Используйте всегда, когда выводите дату пользователю.
- createFromUserTime(): Создает объект из строки, которая считается временем пользователя, и конвертирует ее в серверное время. Используйте всегда, когда получаете дату от пользователя.
// Сервер работает в UTC, у пользователя UTC+3
// 1. Отображение даты пользователю
$serverTime = new DateTime('2024-10-26 12:00:00', 'Y-m-d H:i:s');
$userTime = (clone $serverTime)->toUserTime();
echo $userTime->toString(); // Выведет "26.10.2024 15:00:00"
// 2. Получение даты от пользователя
$userDateString = '27.10.2024 10:00:00'; // Пользователь ввел в форме
$serverTimeForDb = DateTime::createFromUserTime($userDateString);
echo $serverTimeForDb->format('Y-m-d H:i:s'); // Выведет "2024-10-27 07:00:00" - это значение нужно сохранять в БД
5. Интеграция с D7 ORM
При работе с ORM всегда используйте эти объекты для полей DateField и DatetimeField. ORM автоматически преобразует их в строковый формат, понятный базе данных.
use Bitrix\Iblock\ElementTable;
use Bitrix\Main\Type\DateTime;
// Добавление элемента
ElementTable::add([
'IBLOCK_ID' => 5,
'NAME' => 'Событие',
'ACTIVE_FROM' => new DateTime('2025-01-01 10:00:00', 'Y-m-d H:i:s')
]);
// Фильтрация (найти будущие события)
$result = ElementTable::getList([
'filter' => [
'>ACTIVE_FROM' => new DateTime() // Сравнение с текущим серверным временем
]
]);
Сравнение с API старого ядра
Задача | Старый API (Не рекомендуется) | D7 API (Современный подход) |
Создать дату из строки | MakeTimeStamp(«26.10.2024») | new Date(«26.10.2024») |
Проверить дату | CheckDateTime(«26.10.2024») | Date::isCorrect(«26.10.2024») |
Форматировать | FormatDate(«d.m.Y», $ts) | $date->format(«d.m.Y») |
Прибавить день | $ts + 86400 (небезопасно из-за DST) | $date->add(«1 day») |
Учет часовых поясов | ConvertTimeStamp(), CTimeZone | toUserTime(), createFromUserTime() |
Вывод:
Классы DateTime и Date из \Bitrix\Main\Type — это современный, безопасный и обязательный к использованию инструмент для работы с датами.
Они решают множество проблем со строковыми форматами и часовыми поясами, прекрасно интегрируются с D7 ORM и делают ваш код значительно чище и надежнее.
Bitrix D7, DateTime, Date, Type\DateTime, работа с датами, часовой пояс, timezone, формат даты, getTimestamp, add, modify, toUserTime, createFromUserTime, isCorrect, ORM.