1
0
mirror of https://github.com/php/doc-ru.git synced 2026-03-27 17:22:14 +01:00
Files
archived-doc-ru/reference/datetime/datetimeimmutable/createfromformat.xml
2023-12-12 22:29:45 +03:00

832 lines
36 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 280c1486811039092af54aa172a05417372bebb9 Maintainer: shein Status: ready -->
<!-- Reviewed: no -->
<refentry xml:id="datetimeimmutable.createfromformat" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>DateTimeImmutable::createFromFormat</refname>
<refname>date_create_immutable_from_format</refname>
<refpurpose>Разбирает строку с датой согласно указанному формату</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<para>&style.oop;</para>
<methodsynopsis role="DateTimeImmutable">
<modifier>public</modifier> <modifier>static</modifier> <type class="union"><type>DateTimeImmutable</type><type>false</type></type><methodname>DateTimeImmutable::createFromFormat</methodname>
<methodparam><type>string</type><parameter>format</parameter></methodparam>
<methodparam><type>string</type><parameter>datetime</parameter></methodparam>
<methodparam choice="opt"><type class="union"><type>DateTimeZone</type><type>null</type></type><parameter>timezone</parameter><initializer>&null;</initializer></methodparam>
</methodsynopsis>
<para>&style.procedural;</para>
<methodsynopsis>
<type class="union"><type>DateTimeImmutable</type><type>false</type></type><methodname>date_create_immutable_from_format</methodname>
<methodparam><type>string</type><parameter>format</parameter></methodparam>
<methodparam><type>string</type><parameter>datetime</parameter></methodparam>
<methodparam choice="opt"><type class="union"><type>DateTimeZone</type><type>null</type></type><parameter>timezone</parameter><initializer>&null;</initializer></methodparam>
</methodsynopsis>
<para>
Возвращает новый объект DateTimeImmutable, представляющий дату и время,
указанные строкой в параметре <parameter>datetime</parameter>,
которые были отформатированы в заданном формате <parameter>format</parameter>.
</para>
</refsect1>
<refsect1 role="parameters" xml:id="datetimeimmutable.createfromformat.parameters">
&reftitle.parameters;
<variablelist>
<varlistentry>
<term><parameter>format</parameter></term>
<listitem>
<para>
Формат даты и времени в виде строки (<type>string</type>), которому
соответствует значение второго аргумента функции. Список вариантов
форматирования представлен ниже. В большинстве случаев, при форматировании
используются те же символы, что и в функции <function>date</function>.
</para>
<para>
Все поля инициализируются с текущей датой/временем. В большинстве случаев будет необходимо
их "обнулить" (эпоха Unix, <literal>1970-01-01 00:00:00 UTC</literal>).
Для этого нужно добавить символ <literal>!</literal> в качестве первого символа
параметра <parameter>format</parameter> или <literal>|</literal> в качестве последнего.
Для получения дополнительной информации смотрите документацию по каждому символу ниже.
</para>
<para>
Формат разбирается слева направо, это означает, что в некоторых ситуациях порядок присутствия символов формата влияет на результат.
В случае <literal>z</literal> (день года) требуется, чтобы год уже был разобран,
например, с помощью символов <literal>Y</literal> или <literal>y</literal>.
</para>
<para>
Символы для разбора чисел допускают широкий диапазон значений,
выходящий за пределы логического диапазона. Например, <literal>d</literal> (день месяца) принимает значения
в диапазоне от <literal>00</literal> до <literal>99</literal>.
Единственным ограничением является количество цифр.
Когда задаются выходящие за пределы диапазона значения,
срабатывает механизм переполнения анализатора даты/времени.
Ниже показано несколько примеров такого поведения.
</para>
<para>
Это означает, что разобранные данные для буквы формата являются жадными
и будут считываться до количества цифр, допускаемого форматом.
Также это означает, что в строке <parameter>datetime</parameter> уже не хватает
символов для следующих символов формата. Пример на этой странице также иллюстрирует эту проблему.
</para>
<para>
<table>
<title>Список возможных символов для составления строки
<parameter>format</parameter>
</title>
<tgroup cols="3">
<thead>
<row>
<entry>Символ в строке <parameter>format</parameter></entry>
<entry>Описание</entry>
<entry>Возможные значения</entry>
</row>
</thead>
<tbody>
<row>
<entry align="center"><emphasis>День</emphasis></entry>
<entry>---</entry>
<entry>---</entry>
</row>
<row>
<entry><literal>d</literal> и <literal>j</literal></entry>
<entry>
День месяца, 2 цифры с нулём в начале или без него
</entry>
<entry>
От <literal>01</literal> до <literal>31</literal> либо
от <literal>1</literal> до <literal>31</literal>.
(допускается использование двузначных чисел, превышающих количество дней в месяце,
в этом случае разница переносится на следующий месяц. Например, использование числа 33 с январём означает 2 февраля)
</entry>
</row>
<row>
<entry><literal>D</literal> и <literal>l</literal></entry>
<entry>
Текстовое представление дня недели
</entry>
<entry>
От <literal>Mon</literal> до <literal>Sun</literal> либо
от <literal>Sunday</literal> до <literal>Saturday</literal>.
Если заданное имя дня отличается от имени дня, принадлежащего разобранной дате (или дате по умолчанию),
то происходит переполнение до <emphasis>следующей</emphasis> даты с заданным именем дня.
Смотрите примеры ниже для объяснения.
</entry>
</row>
<row>
<entry><literal>S</literal></entry>
<entry>
Суффикс для числа в английской нумерации, 2 буквы. Эти буквы
будут пропущены при разборе строки.
</entry>
<entry>
<literal>st</literal>, <literal>nd</literal>, <literal>rd</literal> или
<literal>th</literal>.
</entry>
</row>
<row>
<entry><literal>z</literal></entry>
<entry>
Номер дня с начала года (начиная с 0);
должно предшествовать <literal>Y</literal> или <literal>y</literal>.
</entry>
<entry>
C <literal>0</literal> по <literal>365</literal>.
(Допускаются трёхзначные числа, превышающие числа в году, в этом случае разница переносится на следующий год.
Например, использование числа 366 с 2022 годом означает 2 января 2023 года)
</entry>
</row>
<row>
<entry align="center"><emphasis>Месяц</emphasis></entry>
<entry>---</entry>
<entry>---</entry>
</row>
<row>
<entry><literal>F</literal> и <literal>M</literal></entry>
<entry>
Текстовое представление месяца, например January или Sept
</entry>
<entry>
С <literal>January</literal> по <literal>December</literal> либо
с <literal>Jan</literal> по <literal>Dec</literal>
</entry>
</row>
<row>
<entry><literal>m</literal> и <literal>n</literal></entry>
<entry>
Числовое представление месяца с первым нулём или без него
</entry>
<entry>
С <literal>01</literal> по <literal>12</literal> либо
с <literal>1</literal> по <literal>12</literal>.
(Допускаются двузначные числа больше 12, в этом случае разница переносится на следующий год.
Например, использование числа 13 означает январь в следующем году)
</entry>
</row>
<row>
<entry align="center"><emphasis>Год</emphasis></entry>
<entry>---</entry>
<entry>---</entry>
</row>
<row>
<entry><literal>X</literal> и <literal>x</literal></entry>
<entry>
Полное числовое представление года, до 19 цифр,
с префиксом <literal>+</literal> или <literal>-</literal>.
</entry>
<entry>
Примеры: <literal>0055</literal>, <literal>787</literal>,
<literal>1999</literal>, <literal>-2003</literal>,
<literal>+10191</literal>
</entry>
</row>
<row>
<entry><literal>Y</literal></entry>
<entry>
Полное числовое представление года, до 4 цифр.
</entry>
<entry>
Примеры: <literal>0055</literal>, <literal>787</literal>,
<literal>1999</literal>, <literal>2003</literal>.
</entry>
</row>
<row>
<entry><literal>y</literal></entry>
<entry>
2 цифры в представлении года (в диапазоне 1970-2069 включительно)
</entry>
<entry>
Примеры:
<literal>99</literal> или <literal>03</literal>
(будет расшифровано как <literal>1999</literal> и
<literal>2003</literal> соответственно)
</entry>
</row>
<row>
<entry align="center"><emphasis>Время</emphasis></entry>
<entry>---</entry>
<entry>---</entry>
</row>
<row>
<entry><literal>a</literal> и <literal>A</literal></entry>
<entry>
До полудня и После полудня
</entry>
<entry><literal>am</literal> или <literal>pm</literal></entry>
</row>
<row>
<entry><literal>g</literal> и <literal>h</literal></entry>
<entry>
12-ти часовой формат времени с первым нулём или без него
</entry>
<entry>
С <literal>1</literal> по <literal>12</literal> либо
с <literal>01</literal> по <literal>12</literal>.
(допускается использование двузначных чисел больше 12, в этом случае разница переносится на следующий день.
Например, использование числа <literal>14</literal> означает <literal>02</literal> в следующем периоде AM/PM)
</entry>
</row>
<row>
<entry><literal>G</literal> и <literal>H</literal></entry>
<entry>
24-х часовой формат времени с нулём в начале или без него
</entry>
<entry>
С <literal>0</literal> по <literal>23</literal> или
с <literal>00</literal> по <literal>23</literal> (допускаются
двузначные числа больше 24, в этом случае разница переносится на следующий день.
Например, использование <literal>26</literal> означает <literal>02:00</literal> следующего дня)
</entry>
</row>
<row>
<entry><literal>i</literal></entry>
<entry>
Минуты с нулём в начале
</entry>
<entry>
С <literal>00</literal> по <literal>59</literal>.
(допускается использование двузначных чисел больше 59, в этом случае разница переносится на следующий час.
Например, использование числа <literal>66</literal> означает <literal>:06</literal> следующего часа)
</entry>
</row>
<row>
<entry><literal>s</literal></entry>
<entry>Секунды с нулём в начале</entry>
<entry>
От <literal>00</literal> до <literal>59</literal>.
(допускаются двузначные числа больше 59, в этом случае разница переносится на следующую минуту.
Например, использование числа <literal>90</literal> означает <literal>:30</literal> следующей минуты)
</entry>
</row>
<row>
<entry><literal>v</literal></entry>
<entry>Дробь в миллисекундах (до 3 цифр)</entry>
<entry>Примеры: <literal>12</literal> (<literal>0.12</literal> секунд), <literal>345</literal> (<literal>0.345</literal> секунд)</entry>
</row>
<row>
<entry><literal>u</literal></entry>
<entry>Дробь в микросекундах (до 6 цифр)</entry>
<entry>Примеры: <literal>45</literal> (<literal>0.45</literal> секунд), <literal>654321</literal> (<literal>0.654321</literal> секунд)</entry>
</row>
<row>
<entry align="center"><emphasis>Часовой пояс</emphasis></entry>
<entry>---</entry>
<entry>---</entry>
</row>
<row>
<entry>
<literal>e</literal>, <literal>O</literal>,
<literal>P</literal> и <literal>T</literal>
</entry>
<entry>
Идентификатор часового пояса, либо разница в часах относительно
UTC, либо разница относительно UTC с двоеточием между часами и минутами,
либо аббревиатура часового пояса
</entry>
<entry>Примеры: <literal>UTC</literal>, <literal>GMT</literal>,
<literal>Atlantic/Azores</literal> или
<literal>+0200</literal> или <literal>+02:00</literal> или
<literal>EST</literal>, <literal>MDT</literal>
</entry>
</row>
<row>
<entry align="center"><emphasis>Дата/Время полностью</emphasis></entry>
<entry>---</entry>
<entry>---</entry>
</row>
<row>
<entry><literal>U</literal></entry>
<entry>
Количество секунд с начала Эпохи Unix (January 1 1970 00:00:00 GMT)
</entry>
<entry>Пример: <literal>1292177455</literal></entry>
</row>
<row>
<entry align="center"><emphasis>Пробел и Разделители</emphasis></entry>
<entry>---</entry>
<entry>---</entry>
</row>
<row>
<entry><literal> </literal> (пробел)</entry>
<entry>Ноль или несколько символов пробела, табуляции, неразрывного пробела NBSP (U+A0) или узкого неразрывного пробела NNBSP (U+202F)</entry>
<entry>Пример: <literal>"\t"</literal>, <literal>" "</literal></entry>
</row>
<row>
<entry><literal>#</literal></entry>
<entry>
Один из следующих символов: <literal>;</literal>,
<literal>:</literal>, <literal>/</literal>, <literal>.</literal>,
<literal>,</literal>, <literal>-</literal>, <literal>(</literal> или
<literal>)</literal>
</entry>
<entry>Пример: <literal>/</literal></entry>
</row>
<row>
<entry>
<literal>;</literal>,
<literal>:</literal>, <literal>/</literal>, <literal>.</literal>,
<literal>,</literal>, <literal>-</literal>, <literal>(</literal> или
<literal>)</literal>
</entry>
<entry>Символ разделитель.</entry>
<entry>Пример: <literal>-</literal></entry>
</row>
<row>
<entry><literal>?</literal></entry>
<entry>Один случайный (любой) символ</entry>
<entry>
Пример: <literal>^</literal> (Будьте внимательны: в UTF-8
кодировке вам может потребоваться более одного <literal>?</literal>,
так как там один символ может занимать более одного байта. В таких
случаях может помочь использование <literal>*</literal>.
</entry>
</row>
<row>
<entry><literal>*</literal></entry>
<entry>
Любое количество любых символов до следующего разделителя
</entry>
<entry>
Пример: <literal>*</literal> в <literal>Y-*-d</literal> для
строки <literal>2009-aWord-08</literal> будет соответствовать
<literal>aWord</literal>
</entry>
</row>
<row>
<entry><literal>!</literal></entry>
<entry>
Сбрасывает все поля (год, месяц, день, час, минута, секунда и часовой пояс) до нулевых значений
(<literal>0</literal> для часа, минуты, секунды,
<literal>1</literal> для месяца и дня,
<literal>1970</literal> для года и
<literal>UTC</literal> для информации о часовом поясе).
</entry>
<entry>
Без <literal>!</literal> все поля будут соответствовать
текущему времени.
</entry>
</row>
<row>
<entry><literal>|</literal></entry>
<entry>
Сбрасывает значения незаданных полей (год, месяц, день, час, минута,
секунда, часовой пояс) до нулевых значений.
</entry>
<entry>
<literal>Y-m-d|</literal> установит год, месяц и день в соответствии
с данными в строке, а часы, минуты и секунды установит в 0.
</entry>
</row>
<row>
<entry><literal>+</literal></entry>
<entry>
Если задан этот спецификатор, данные, завершающие строку (нуль байт
например) не будут вызывать ошибку, только предупреждение
</entry>
<entry>
Используйте <methodname>DateTime::getLastErrors</methodname>
для определения, были ли в строке завершающие символы.
</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
Наличие в строке формата нераспознаваемых символов, отсутствующих
в списке выше, приведёт к ошибке разбора строки. В этом случае
сообщение об ошибке будет добавлено в возвращаемую структуру.
Получить это сообщение можно с помощью функции
<methodname>DateTime::getLastErrors</methodname>.
</para>
<para>
Для вставки в <parameter>format</parameter> буквенного символа, вы
должны экранировать его с помощью обратного слеша(<literal>\</literal>).
</para>
<para>
Если <parameter>format</parameter> не содержит символ
<literal>!</literal>, то значения полей, не заданных в строке
формата, будут установлены в соответствии с текущим временем.
</para>
<para>
Если <parameter>format</parameter> содержит символ
<literal>!</literal>, то значения полей, не заданных в строке
формата (равно как и значения полей слева от
<literal>!</literal>) будут установлены в соответствии со
значениями полей начала Эпохи Unix.
</para>
<para>
Если любой символ времени разобран, то все остальные поля, связанные с временем,
устанавливаются в "0", если они также не разобраны.
</para>
<para>
Начало эпохи Unix 1970-01-01 00:00:00 UTC.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>datetime</parameter></term>
<listitem>
<para>
Строка, представляющая время.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>timezone</parameter></term>
<listitem>
<para>
Объект класса <classname>DateTimeZone</classname>, представляющий
ожидаемый часовой пояс.
</para>
<para>
Если <parameter>timezone</parameter> не указан или &null; и
<parameter>datetime</parameter> не содержит часовой пояс,
то будет использован текущий часовой пояс.
</para>
<note>
<para>
Параметр <parameter>timezone</parameter> и
текущий часовой пояс будут проигнорированы,
если параметр <parameter>datetime</parameter> также
содержит метку времени UNIX (то есть timestamp вида <literal>946684800</literal>)
или же указанный часовой пояс (то есть <literal>2010-01-28T15:00:00+02:00</literal>).
</para>
</note>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
Возвращает новый экземпляр DateTimeImmutable&return.falseforfailure;.
</para>
</refsect1>
<refsect1 role="errors">
&reftitle.errors;
<para>
Функция выбрасывает <exceptionname>ValueError</exceptionname>,
если параметр <parameter>datetime</parameter> содержит нулевые байты.
</para>
</refsect1>
<refsect1 role="changelog">
&reftitle.changelog;
<para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>&Version;</entry>
<entry>&Description;</entry>
</row>
</thead>
<tbody>
<row>
<entry>8.2.9</entry>
<entry>
Спецификатор <literal> </literal> (пробел) теперь также поддерживает символы
неразрывного пробела NBSP
(U+A0) и узкого неразрывного пробела NNBSP (U+202F).
</entry>
</row>
<row>
<entry>8.2.0</entry>
<entry>
Добавлены спецификаторы <literal>X</literal> и <literal>x</literal>
параметру <parameter>format</parameter>.
</entry>
</row>
<row>
<entry>8.0.21, 8.1.8, 8.2.0</entry>
<entry>
Теперь, когда в параметр <parameter>datetime</parameter> передаются нулевые байты,
выбрасывается исключение <exceptionname>ValueError</exceptionname>,
ранее такая ситуация игнорировалась.
</entry>
</row>
<row>
<entry>7.3.0</entry>
<entry>
Добавлен спецификатор <literal>v</literal> параметру <parameter>format</parameter>.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<example>
<title>Пример использования <function>DateTimeImmutable::createFromFormat</function></title>
<para>&style.oop;</para>
<programlisting role="php">
<![CDATA[
<?php
$date = DateTimeImmutable::createFromFormat('j-M-Y', '15-Feb-2009');
echo $date->format('Y-m-d');
?>
]]>
</programlisting>
</example>
<example>
<title>Использование предопределённых констант формата с помощью <function>DateTimeImmutable::createFromFormat</function></title>
<para>&style.oop;</para>
<programlisting role="php">
<![CDATA[
<?php
$date = DateTimeImmutable::createFromFormat(DateTimeInterface::ISO8601, '2004-02-12T15:19:21+00:00');
$date = DateTimeImmutable::createFromFormat(DateTimeInterface::RFC3339_EXTENDED, '2013-10-14T09:00:00.000+02:00');
?>
]]>
</programlisting>
<para>
<link linkend="datetimeinterface.constants.types">Константы форматирования</link>,
используемые в данном примере, состоят из строки символов
для <link linkend="datetime.format">форматирования</link> объекта <classname>DateTimeImmutable</classname>.
В большинстве случаев эти буквы совпадают с теми же элементами информации о дате/времени,
которые определены в <link linkend="datetimeimmutable.createfromformat.parameters">параметрах</link> выше,
но они, как правило, более мягкие.
</para>
</example>
<example>
<title>Тонкости <function>DateTimeImmutable::createFromFormat</function></title>
<programlisting role="php">
<![CDATA[
<?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";
?>
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
Текущее время: 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
]]>
</screen>
</example>
<example>
<title>Форматирование строки с помощью литеральных символов</title>
<programlisting role="php">
<![CDATA[
<?php
echo DateTimeImmutable::createFromFormat('H\h i\m s\s','23h 15m 03s')->format('H:i:s');
?>
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
23:15:03
]]>
</screen>
</example>
<example>
<title>Поведение при переполнении</title>
<programlisting role="php">
<![CDATA[
<?php
echo DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2021-17-35 16:60:97')->format(DateTimeImmutable::RFC2822);
?>
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
Sat, 04 Jun 2022 17:01:37 +0000
]]>
</screen>
<para>
Хотя результат выглядит странно, он правильный, так как случаются следующие переполнения:
</para>
<orderedlist>
<listitem>
<simpara>
<literal>97</literal> секунд переваливают за <literal>1</literal> минуту,
оставляя <literal>37</literal> секунд.
</simpara>
</listitem>
<listitem>
<simpara>
<literal>61</literal> минут переваливает за <literal>1</literal> час,
оставляя <literal>1</literal> минуту.
</simpara>
</listitem>
<listitem>
<simpara>
<literal>35</literal> дней переваливают за <literal>1</literal> месяц,
оставляя <literal>4</literal> дня. Количество оставшихся дней зависит от месяца,
так как не в каждом месяце одинаковое количество дней.
</simpara>
</listitem>
<listitem>
<simpara>
<literal>18</literal> месяцев переваливают за <literal>1</literal> год,
оставляя <literal>6</literal> месяцев.
</simpara>
</listitem>
</orderedlist>
</example>
<example>
<title>Поведение имени переполненного дня</title>
<programlisting role="php">
<![CDATA[
<?php
$d = DateTime::createFromFormat(DateTimeInterface::RFC1123, 'Mon, 3 Aug 2020 25:00:00 +0000');
echo $d->format(DateTime::RFC1123), "\n";
?>
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
Mon, 10 Aug 2020 01:00:00 +0000
]]>
</screen>
<para>
Хотя результат выглядит странно, он правильный, так как случаются следующие переполнения:
</para>
<orderedlist>
<listitem>
<simpara>
<literal>3 Aug 2020 25:00:00</literal> переваливает за <literal>(Tue) 4 Aug
2020 01:00</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Применяется <literal>Mon</literal>, что переводит дату на <literal>Mon, 10 Aug 2020 01:00:00</literal>.
Объяснение относительных ключевых слов, таких как <literal>Mon</literal>,
описано в разделе <link linkend="datetime.formats.relative">относительные форматы</link>.
</simpara>
</listitem>
</orderedlist>
</example>
<para>
Для обнаружения переполнений в датах можно использовать метод
<methodname>DateTimeImmutable::getLastErrors</methodname>,
который будет включать предупреждение, если произошло переполнение.
</para>
<example>
<title>Обнаружение переполнения дат</title>
<programlisting role="php">
<![CDATA[
<?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());
?>
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
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) {
}
}
]]>
</screen>
</example>
<example>
<title>Жадное поведение при разборе</title>
<programlisting role="php">
<![CDATA[
<?php
print_r(date_parse_from_format('Gis', '60101'));
?>
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
Array
(
[year] =>
[month] =>
[day] =>
[hour] => 60
[minute] => 10
[second] => 0
[fraction] => 0
[warning_count] => 1
[warnings] => Array
(
[5] => The parsed time was invalid
)
[error_count] => 1
[errors] => Array
(
[4] => A two digit second could not be found
)
[is_localtime] =>
)
]]>
</screen>
<para>
Формат <literal>G</literal> предназначен для разбора 24-часовых часов
с ведущим нулём или без него. Для этого необходимо разобрать 1 или 2 цифры.
Так как есть две следующие цифры, он жадно считывает это как <literal>60</literal>.
</para>
<para>
Следующие символы формата <literal>i</literal> и <literal>s</literal> требуют двух цифр.
Это означает, что <literal>10</literal> передаётся как минута (<literal>i</literal>)
и что затем остаётся недостаточно цифр для разбора секунд (<literal>s</literal>).
</para>
<para>
На эту проблему указывает массив <literal>errors</literal>.
</para>
<para>
Кроме того, час <literal>60</literal> находится вне диапазона
<literal>0</literal>-<literal>24</literal>, что добавляет предупреждение
в массив <literal>warnings</literal> о том, что время является недействительным.
</para>
</example>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<simplelist>
<member><function>DateTimeImmutable::__construct</function></member>
<member><function>DateTimeImmutable::getLastErrors</function></member>
<member><function>checkdate</function></member>
<member><function>strptime</function></member>
</simplelist>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->