Разбор дат в PHP
Узнайте, как использовать date_parse_from_format() в PHP для разбора строк дат по заданному формату и проверки результата.
Даты нередко поступают в виде обычных строк — из полей формы, CSV-файлов или ответов API — и PHP не знает, как эти строки структурированы, пока вы ему не укажете. Функция date_parse_from_format() позволяет разобрать строку даты по явно заданному формату и проверить результат, включая ошибки и предупреждения. На этой странице рассматривается, как работает функция, как читать возвращаемое значение, как проверять входные данные и когда стоит выбрать другой инструмент, например DateTime или strtotime().
Что такое разбор дат
Разбор дат — это процесс превращения строки вроде "2023-03-03" в структурированные данные — год, месяц, день и т. д. — с которыми ваша программа может работать. Сложность состоит в неоднозначности: 03/04/2023 может означать 4 марта или 3 апреля в зависимости от принятого соглашения, а 2023-13-45 похоже на дату, но ею не является.
date_parse_from_format() устраняет эту неоднозначность: вы заранее указываете точный формат, функция строго разбирает строку в соответствии с ним и сообщает о результате, чтобы вы могли решить, корректны ли входные данные.
Функция date_parse_from_format()
date_parse_from_format() разбирает строку даты по конкретному формату и возвращает ассоциативный array с описанием разобранной даты: год, месяц, день, час, минута, секунда, а также предупреждения и ошибки, возникшие при чтении строки.
Синтаксис
date_parse_from_format(string $format, string $datetime): array$format— строка формата, использующая те же заполнители, что иdate(), напримерY-m-dдля2023-03-03илиd/m/Yдля03/03/2023.$datetime— строка даты для разбора.
Функция всегда возвращает array и никогда не выбрасывает исключений. Чтобы узнать, успешно ли выполнен разбор, необходимо проверить ключи error_count и warning_count.
Базовый пример
Результат выполнения этого кода:
Array
(
[year] => 2023
[month] => 3
[day] => 3
[hour] => 10
[minute] => 30
[second] => 0
[fraction] =>
[warning_count] => 0
[warnings] => Array()
[error_count] => 0
[errors] => Array()
[is_localtime] =>
[zone_type] => 1
[zone] => -14400
[is_dst] =>
)Функция разобрала "2023-03-03 10:30:00" по формату Y-m-d H:i:s и заполнила каждый компонент. Вы можете обращаться к отдельным значениям напрямую, например $date_array['year'] или $date_array['month']. Если какой-либо компонент отсутствует в строке формата, его значение возвращается как false (отображается в виде пустого значения при выводе через print_r).
Разбор нестандартных форматов
Заполнители формата совпадают с теми, что используются в date(), поэтому любой формат, который вы можете создать, вы можете и разобрать. Пример ниже читает дату в европейском стиле день/месяц/год:
<?php
$result = date_parse_from_format("d/m/Y", "03/03/2023");
echo "Day: {$result['day']}\n";
echo "Month: {$result['month']}\n";
echo "Year: {$result['year']}\n";Это выведет:
Day: 3
Month: 3
Year: 2023Поскольку в формате присутствуют только d, m и Y, ключи hour, minute и second возвращаются как false.
Проверка результата: ошибки и предупреждения
date_parse_from_format() никогда не выбрасывает исключений — даже при некорректных входных данных функция возвращает array. О пригодности входных данных сообщают два ключа:
error_countподсчитывает символы, которые вообще не совпали с форматом.warning_countподсчитывает значения, которые соответствуют формату, но лишены смысла, например месяц13или день45.
Строка, не совпадающая с форматом, порождает ошибки:
<?php
// Expecting Y-m-d but the input is d/m/Y
$result = date_parse_from_format("Y-m-d", "03/03/2023");
echo "Errors: {$result['error_count']}\n";
print_r($result['errors']);Errors: 5
Array
(
[2] => Unexpected data found.
[5] => Unexpected data found.
[8] => Trailing data
)Строка, совпадающая с форматом, но не являющаяся реальной датой, порождает предупреждение:
<?php
$result = date_parse_from_format("Y-m-d", "2023-13-45");
echo "Warnings: {$result['warning_count']}\n";
print_r($result['warnings']);Warnings: 1
Array
(
[10] => The parsed date was invalid
)Всегда проверяйте оба счётчика, прежде чем доверять разобранным значениям:
if ($result['error_count'] === 0 && $result['warning_count'] === 0) {
// safe to use $result['year'], $result['month'], etc.
}Когда стоит использовать другую функцию
date_parse_from_format() лучше всего подходит, когда вам нужен подробный отчёт с учётом формата — особенно для проверки входных данных. Если вам просто нужно готовое значение даты, другие инструменты удобнее:
DateTime::createFromFormat($format, $string)возвращает готовый к использованию объектDateTime, с которым можно форматировать или выполнять арифметические операции. См. PHP date and time.strtotime()самостоятельно угадывает формат и возвращает Unix-временную метку — удобно для распространённых однозначных строк, но рискованно для форматов, зависящих от локали.date_parse()аналогична этой функции, но без строки формата; она пытается интерпретировать дату самостоятельно.
Заключение
date_parse_from_format() разбирает строку даты по явно заданному формату и возвращает подробный ассоциативный array, что делает её идеальной для проверки дат, введённых пользователем. Помните, что функция никогда не выбрасывает исключений — проверяйте error_count и warning_count перед использованием результата. Когда вам нужен объект DateTime или временная метка, воспользуйтесь DateTime::createFromFormat() или strtotime().