SymfonyWorld Online 2022 Winter Edition

DateTimeImmutable::createFromFormat

date_create_immutable_from_format

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

DateTimeImmutable::createFromFormat -- date_create_immutable_from_formatРазбирает строку с датой согласно указанному формату

Описание

Объектно-ориентированный стиль

public static DateTimeImmutable::createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): DateTimeImmutable|false

Процедурный стиль

date_create_immutable_from_format(string $format, string $datetime, ?DateTimeZone $timezone = null): DateTimeImmutable|false

Возвращает новый объект DateTimeImmutable, представляющий дату и время, указанные строкой в параметре datetime, которые были отформатированы в заданном формате format.

Список параметров

format

Формат даты и времени в виде строки (string), которому соответствует значение второго аргумента функции. Список вариантов форматирования представлен ниже. В большинстве случаев, при форматировании используются те же символы, что и в функции date().

Формат разбирается слева направо, это означает, что в некоторых ситуациях порядок присутствия символов формата влияет на результат. В случае z (день года) требуется, чтобы год уже был разобран, например, с помощью символов Y или y.

Символы, используемые для разбора чисел, допускают широкий диапазон значений, выходящий за пределы логического диапазона. Например, d (день месяца) принимает значения в диапазоне от 00 до 99. Единственным ограничением является количество цифр. Механизм переполнения парсера даты/времени используется, когда задаются значения, выходящие за пределы диапазона. Приведённые ниже примеры демонстрируют некоторые особенности такого поведения.

Список возможных символов для составления строки format
Символ в строке format Описание Возможные значения
День --- ---
d и j День месяца, 2 цифры с нулём в начале или без него От 01 до 31 либо от 1 до 31. (допускается использование двузначных чисел, превышающих количество дней в месяце, в этом случае разница переносится на следующий месяц. Например, использование числа 33 с январём означает 2 февраля)
D и l Текстовое представление дня недели От Mon до Sun либо от Sunday до Saturday. Если заданное имя дня отличается от имени дня, принадлежащего разобранной дате (или дате по умолчанию), то происходит переполнение до следующей даты с заданным именем дня. Смотрите примеры ниже для объяснения.
S Суффикс для числа в английской нумерации, 2 буквы. Эти буквы будут пропущены при разборе строки. st, nd, rd или th.
z Номер дня с начала года (начиная с 0); должно предшествовать Y или y. C 0 по 365. (Допускаются трёхзначные числа, превышающие числа в году, в этом случае разница переносится на следующий год. Например, использование числа 366 с 2022 годом означает 2 января 2023 года)
Месяц --- ---
F и M Текстовое представление месяца, например January или Sept С January по December либо с Jan по Dec
m и n Числовое представление месяца с первым нулём или без него С 01 по 12 либо с 1 по 12. (Допускаются двузначные числа больше 12, в этом случае разница переносится на следующий год. Например, использование числа 13 означает январь в следующем году)
Год --- ---
Y Полное числовое представление года, до 4 цифр. Примеры: 0055, 787, 1999, 2003.
y 2 цифры в представлении года (в диапазоне 1970-2069 включительно) Примеры: 99 или 03 (будет расшифровано как 1999 и 2003 соответственно)
Время --- ---
a и A До полудня и После полудня am или pm
g и h 12-ти часовой формат времени с первым нулём или без него С 1 по 12 либо с 01 по 12. (допускается использование двузначных чисел больше 12, в этом случае разница переносится на следующий день. Например, использование числа 14 означает 02 в следующем периоде AM/PM)
G и H 24-х часовой формат времени с нулём в начале или без него С 0 по 23 или с 00 по 23 (допускаются двузначные числа больше 24, в этом случае разница переносится на следующий день. Например, использование 26 означает 02:00 следующего дня)
i Минуты с нулём в начале С 00 по 59. (допускается использование двузначных чисел больше 59, в этом случае разница переносится на следующий час. Например, использование числа 66 означает :06 следующего часа)
s Секунды с нулём в начале От 00 до 59. (допускаются двузначные числа больше 59, в этом случае разница переносится на следующую минуту. Например, использование числа 90 означает :30 следующей минуты)
v Дробь в миллисекундах (до 3 цифр) Примеры: 12 (0.12 секунд), 345 (0.345 секунд)
u Дробь в микросекундах (до 6 цифр) Примеры: 45 (0.45 секунд), 654321 (0.654321 секунд)
Часовой пояс --- ---
e, O, P и T Идентификатор часового пояса, либо разница в часах относительно UTC, либо разница относительно UTC с двоеточием между часами и минутами, либо аббревиатура часового пояса Примеры: UTC, GMT, Atlantic/Azores или +0200 или +02:00 или EST, MDT
Дата/Время полностью --- ---
U Количество секунд с начала Эпохи Unix (January 1 1970 00:00:00 GMT) Пример: 1292177455
Пробел и Разделители --- ---
(пробел) Один пробел или один отступ табуляции Пример:
# Один из следующих символов: ;, :, /, ., ,, -, ( или ) Пример: /
;, :, /, ., ,, -, ( или ) Символ разделитель. Пример: -
? Один случайный (любой) символ Пример: ^ (Будьте внимательны: в UTF-8 кодировке вам может потребоваться более одного ?, так как там один символ может занимать более одного байта. В таких случаях может помочь использование *.
* Любое количество любых символов до следующего разделителя Пример: * в Y-*-d для строки 2009-aWord-08 будет соответствовать aWord
! Сбрасывает все поля (год, месяц, день, час, минута, секунда и часовой пояс) до нулевых значений (0 для часа, минуты, секунды, 1 для месяца и дня, 1970 для года и UTC для информации о часовом поясе). Без ! все поля будут соответствовать текущему времени.
| Сбрасывает значения незаданных полей (год, месяц, день, час, минута, секунда, часовой пояс) до нулевых значений. Y-m-d| установит год, месяц и день в соответствии с данными в строке, а часы, минуты и секунды установит в 0.
+ Если задан этот спецификатор, данные, завершающие строку (нуль байт например) не будут вызывать ошибку, только предупреждение Используйте DateTime::getLastErrors() для определения, были ли в строке завершающие символы.

Наличие в строке формата нераспознаваемых символов, отсутствующих в списке выше, приведёт к ошибке разбора строки. В этом случае сообщение об ошибке будет добавлено в возвращаемую структуру. Получить это сообщение можно с помощью функции DateTime::getLastErrors().

Для вставки в format буквенного символа, вы должны экранировать его с помощью обратного слеша(\).

Если format не содержит символ !, то значения полей, не заданных в строке формата, будут установлены в соответствии с текущим временем.

Если format содержит символ !, то значения полей, не заданных в строке формата (равно как и значения полей слева от !) будут установлены в соответствии со значениями полей начала Эпохи Unix.

Если любой символ времени разобран, то все остальные поля, связанные с временем, устанавливаются в "0", если они также не разобраны.

Начало эпохи Unix 1970-01-01 00:00:00 UTC.

datetime

Строка, представляющая время.

timezone

Объект класса DateTimeZone, представляющий ожидаемый часовой пояс.

Если timezone не указан или null и datetime не содержит часовой пояс, то будет использован текущий часовой пояс.

Замечание:

Параметр timezone и текущий часовой пояс будут проигнорированы, если параметр datetime также содержит метку времени UNIX (то есть timestamp вида 946684800) или же указанный часовой пояс (то есть 2010-01-28T15:00:00+02:00).

Возвращаемые значения

Возвращает новый экземпляр DateTimeImmutable или false в случае возникновения ошибки.

Список изменений

Версия Описание
7.3.0 Добавлен спецификатор v параметру format.

Примеры

Пример #1 Пример использования DateTimeImmutable::createFromFormat()

Объектно-ориентированный стиль

<?php
$date 
DateTimeImmutable::createFromFormat('j-M-Y''15-Feb-2009');
echo 
$date->format('Y-m-d');
?>

Пример #2 Тонкости DateTimeImmutable::createFromFormat()

<?php
echo 'Текущее время: ' date('Y-m-d H:i:s') . "\n";

$format 'Y-m-d';
$date DateTimeImmutable::createFromFormat($format'2009-02-15');
echo 
"Формат: $format; " $date->format('Y-m-d H:i:s') . "\n";

$format 'Y-m-d H:i:s';
$date DateTimeImmutable::createFromFormat($format'2009-02-15 15:16:17');
echo 
"Формат: $format; " $date->format('Y-m-d H:i:s') . "\n";

$format 'Y-m-!d H:i:s';
$date DateTimeImmutable::createFromFormat($format'2009-02-15 15:16:17');
echo 
"Формат: $format; " $date->format('Y-m-d H:i:s') . "\n";

$format '!d';
$date DateTimeImmutable::createFromFormat($format'15');
echo 
"Формат: $format; " $date->format('Y-m-d H:i:s') . "\n";

$format 'i';
$date DateTimeImmutable::createFromFormat($format'15');
echo 
"Формат: $format; " $date->format('Y-m-d H:i:s') . "\n";
?>

Результатом выполнения данного примера будет что-то подобное:

Текущее время: 2022-06-02 15:50:46
Формат: Y-m-d; 2009-02-15 15:50:46
Формат: Y-m-d H:i:s; 2009-02-15 15:16:17
Формат: Y-m-!d H:i:s; 1970-01-15 15:16:17
Формат: !d; 1970-01-15 00:00:00
Формат: i; 2022-06-02 00:15:00

Пример #3 Форматирование строки с помощью литеральных символов

<?php
echo DateTimeImmutable::createFromFormat('H\h i\m s\s','23h 15m 03s')->format('H:i:s');
?>

Результатом выполнения данного примера будет что-то подобное:

23:15:03

Пример #4 Поведение при переполнении

<?php
echo DateTimeImmutable::createFromFormat('Y-m-d H:i:s''2021-17-35 16:60:97')->format(DateTimeImmutable::RFC2822);
?>

Результатом выполнения данного примера будет что-то подобное:

Sat, 04 Jun 2022 17:01:37 +0000

Хотя результат выглядит странно, он правильный, так как случаются следующие переполнения:

  1. 97 секунд переваливают за 1 минуту, оставляя 37 секунд.
  2. 61 минут переваливает за 1 час, оставляя 1 минуту.
  3. 35 дней переваливают за 1 месяц, оставляя 4 дня. Количество оставшихся дней зависит от месяца, так как не в каждом месяце одинаковое количество дней.
  4. 18 месяцев переваливают за 1 год, оставляя 6 месяцев.

Пример #5 Поведение имени переполненного дня

<?php
$d 
DateTime::createFromFormat(DateTimeInterface::RFC1123'Mon, 3 Aug 2020 25:00:00 +0000');
echo 
$d->format(DateTime::RFC1123), "\n";
?>

Результатом выполнения данного примера будет что-то подобное:

Mon, 10 Aug 2020 01:00:00 +0000

Хотя результат выглядит странно, он правильный, так как случаются следующие переполнения:

  1. 3 Aug 2020 25:00:00 переваливает за (Tue) 4 Aug 2020 01:00.
  2. Применяется Mon, что переводит дату на Mon, 10 Aug 2020 01:00:00. Объяснение относительных ключевых слов, таких как Mon, описано в разделе относительные форматы.

Для обнаружения переполнений в датах можно использовать метод DateTimeImmutable::getLastErrors(), который будет включать предупреждение, если произошло переполнение.

Пример #6 Обнаружение переполнения дат

<?php
$d 
DateTimeImmutable::createFromFormat('Y-m-d H:i:s''2021-17-35 16:60:97');
echo 
$d->format(DateTimeImmutable::RFC2822), "\n\n";

var_dump(DateTimeImmutable::GetLastErrors());
?>

Результатом выполнения данного примера будет что-то подобное:

Sat, 04 Jun 2022 17:01:37 +0000

array(4) {
  'warning_count' =>
  int(2)
  'warnings' =>
  array(1) {
    [19] =>
    string(27) "The parsed date was invalid"
  }
  'error_count' =>
  int(0)
  'errors' =>
  array(0) {
  }
}

Смотрите также

  • DateTimeImmutable::__construct() - Возвращает новый объект DateTimeImmutable
  • DateTimeImmutable::getLastErrors() - Возвращает предупреждения и ошибки
  • checkdate() - Проверяет корректность даты по григорианскому календарю
  • strptime() - Разбирает строку даты/времени, сгенерированную функцией strftime
add a note

User Contributed Notes

There are no user contributed notes for this page.
To Top