PERSONAL_BIRTHDAY
PERSONAL_BIRTHDAY — поле профиля пользователя в Битрикс. Формат хранения, как получить через UserTable::getList(), типичные проблемы при парсинге даты.
PERSONAL_BIRTHDAY — поле профиля пользователя в 1С-Битрикс, хранящее дату рождения. Располагается в таблице b_user и доступно через D7 ORM-класс BitrixMainUserTable в стандартных выборках пользователей.
Где хранится и как получить PERSONAL_BIRTHDAY
Поле хранится непосредственно в строке таблицы b_user, тип — VARCHAR(255). Несмотря на то что Битрикс обычно записывает дату в формате d.m.Y (например, 15.03.1990), фактический формат зависит от способа заполнения: форма регистрации, административная панель, импорт через CUser::Update() или D7 API. При массовых импортах из CRM, 1C или сторонних систем в поле нередко оказываются ISO-даты, даты с временем или американский формат.
Получение пользователей с заполненным PERSONAL_BIRTHDAY через D7:
<?php
use Bitrix\Main\UserTable;
$result = UserTable::getList([
'select' => ['ID', 'NAME', 'LAST_NAME', 'EMAIL', 'PERSONAL_BIRTHDAY'],
'filter' => [
'=ACTIVE' => 'Y',
'!=PERSONAL_BIRTHDAY' => false, // исключить NULL и пустую строку
'!=EMAIL' => false,
],
'order' => ['ID' => 'ASC'],
'limit' => 500,
]);
while ($user = $result->fetch()) {
$birthday = $user['PERSONAL_BIRTHDAY']; // строка в одном из возможных форматов
// ...
}
Форматы PERSONAL_BIRTHDAY и надёжный парсинг
Битрикс не накладывает жёсткого ограничения на формат поля, поэтому при работе с PERSONAL_BIRTHDAY необходимо проверять несколько вариантов. Наиболее встречаемые:
| Формат | Пример | Описание |
|---|---|---|
d.m.Y | 15.03.1990 | Основной формат Битрикс |
d.m.Y H:i:s | 15.03.1990 00:00:00 | С временем (после некоторых импортов) |
d.m.y | 15.03.90 | Двузначный год |
Y-m-d | 1990-03-15 | ISO 8601 |
Y-m-d H:i:s | 1990-03-15 00:00:00 | ISO с временем |
d/m/Y | 15/03/1990 | Европейский со слешем |
m/d/Y | 03/15/1990 | Американский формат |
Надёжный парсинг через DateTimeImmutable::createFromFormat:
<?php
function parseBirthday(string $value): ?array
{
$value = trim($value);
if ($value === '') {
return null;
}
$formats = [
'd.m.Y',
'd.m.Y H:i:s',
'd.m.y',
'Y-m-d',
'Y-m-d H:i:s',
'd/m/Y',
'm/d/Y',
];
foreach ($formats as $format) {
$birthday = \DateTimeImmutable::createFromFormat($format, $value);
if ($birthday instanceof \DateTimeImmutable) {
return [
'month' => (int)$birthday->format('m'),
'day' => (int)$birthday->format('d'),
];
}
}
// Последняя попытка — strtotime для нестандартных строк
$timestamp = strtotime($value);
if ($timestamp !== false) {
$dt = (new \DateTimeImmutable())->setTimestamp($timestamp);
return [
'month' => (int)$dt->format('m'),
'day' => (int)$dt->format('d'),
];
}
return null;
}
Проблема 29 февраля
Пользователи, рождённые 29 февраля, создают особый случай: в невисокосный год эту дату создать невозможно. Попытка new DateTimeImmutable('2025-02-29') выбросит исключение. При рассылке купонов или поздравлений такого пользователя нельзя просто пропустить.
Рекомендуемое решение — заменять 29 февраля на 28 февраля в невисокосный год:
<?php
function buildBirthdayDate(int $year, int $month, int $day): ?\DateTimeImmutable
{
if (checkdate($month, $day, $year)) {
return new \DateTimeImmutable(sprintf('%04d-%02d-%02d', $year, $month, $day));
}
// Обработка 29 февраля в невисокосный год
if ($month === 2 && $day === 29) {
return new \DateTimeImmutable(sprintf('%04d-02-28', $year));
}
return null;
}
Функция checkdate() корректно учитывает високосность: для 2024 года checkdate(2, 29, 2024) вернёт true, для 2025 — false.