1
0
mirror of https://github.com/php/doc-ja.git synced 2026-03-24 15:12:22 +01:00
Files
archived-doc-ja/reference/datetime/datetimeimmutable/createfromformat.xml
KentarouTakeda e83e3610c2 小規模・独立ファイルの翻訳を一括更新 (#346)
他のファイルに依存しない独立したファイルのうち、英語版との差分が小さいもの(各50行以下)をまとめて更新。

レビュー負荷の少ないファイルを一括で片付けることが目的。

- reference/datetime/datetimezone/gettransitions.xml — DateTimeZone::getTransitions
  1. php/doc-en@77fca2416a

- reference/network/functions/setcookie.xml — setcookie
  1. php/doc-en@b41e78e623
  2. php/doc-en@6122a8317c

- reference/datetime/datetimeimmutable/createfromformat.xml — DateTimeImmutable::createFromFormat
  1. php/doc-en@f5e51d56b0

- reference/pcre/functions/preg-match-all.xml — preg_match_all
  1. php/doc-en@b731f708be

- reference/spl/splfileinfo/iswritable.xml — SplFileInfo::isWritable
  1. php/doc-en@b07b628d6f

- reference/random/functions/rand.xml — rand
  1. php/doc-en@a2a3f35259

- reference/opcache/functions/opcache-is-script-cached.xml — opcache_is_script_cached
  1. php/doc-en@3c36a56c9e

- reference/fpm/status.xml — Status Page
  1. php/doc-en@fa98755da4

- reference/session/functions/session-cache-limiter.xml — session_cache_limiter
  1. php/doc-en@1cef066aa4

- reference/image/functions/imagedestroy.xml — imagedestroy
  1. php/doc-en@02477ebd44

- reference/curl/constants_curl_setopt.xml
  1. php/doc-en@c9888ac6e5

- reference/xhprof/ini.xml
  1. php/doc-en@323cb7d9b9
  2. php/doc-en@d4d5216e7a
2026-03-06 21:36:18 +09:00

811 lines
32 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: f5e51d56b0a4dd7e70dd47ea7eb3c07fdc207ddd Maintainer: takagi Status: ready -->
<!-- Credits: mumumu -->
<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>
書式を文字列で渡します。以下の書式オプションを参照ください。
大半は、<function>date</function> で使える文字と同じです。
</para>
<para>
全てのフィールドは現在の日付/時刻で初期化されます。
ほとんどの場合、これらの値を "ゼロ" (Unix タイムのエポック
<literal>1970-01-01 00:00:00 UTC</literal>) でリセットしたいはずです。
これは、<parameter>format</parameter> の最初の文字に
<literal>!</literal> を入れるか、
最後の文字に <literal>|</literal> を入れることで実現できます。
詳細な情報は、以下で示すそれぞれの文字に関するドキュメントを参照ください。
</para>
<para>
フォーマットの解釈は左から右に行われます。
これは、フォーマット文字が現れる順番が結果に影響する場合があるということです。
たとえば <literal>z</literal>(1年における何番目の日か) の場合、
<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>
(その月の日数分以上の2桁の数値も指定可能ですが、
その月はオーバーフローします。
たとえば January において 33 を指定した場合、
February 2nd という意味になります)
</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>日付の後につける英語の接尾辞。二文字。処理中には無視されます。</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>
<literal>0</literal> から <literal>365</literal>
(1年の日数分以上の3桁の数値も指定可能ですが、
その年はオーバーフローします。
たとえば 2022年において <literal>366</literal>
を指定した場合は、
January 2nd, 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 以上の2桁の数値も指定可能ですが、
その年についてはオーバーフローします。
たとえば <literal>13</literal> の場合は、
翌年の1月という意味になります)
</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桁<emphasis>まで</emphasis>指定可能。オプションで <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 桁<emphasis>まで</emphasis>の数値で表した年</entry>
<entry>例: <literal>25</literal> (<literal>0025</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 以上の2桁の数値も指定可能ですが、
日の指定がオーバーフローします。
たとえば <literal>14</literal> の場合は、
次の午前/午後の <literal>02</literal> 時という意味になります)
</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 より大きな、2桁の値も指定可能ですが、
この場合、日の指定がオーバーフローします。
たとえば、<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 以上の2桁の数値も指定可能ですが、
次の1時間にオーバーフローします。
たとえば <literal>66</literal> の場合は、
次の1時間の <literal>:06</literal> という意味になります)
</entry>
</row>
<row>
<entry><literal>s</literal></entry>
<entry>秒。先頭のゼロを含む</entry>
<entry>
<literal>00</literal> から <literal>59</literal>
(59 以上の2桁の数値も指定可能ですが、
次の分にオーバーフローします。
たとえば <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>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>Y-*-d</literal> の中の <literal>*</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>
タイムゾーンについてはデフォルトのタイムゾーン)
にリセットします。
</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> が含まれない場合は、作成した時刻値のうち
<parameter>format</parameter> で指定されていない部分を
現在のシステム時刻で初期化します。
</para>
<para>
<parameter>format</parameter> に文字
<literal>!</literal> が含まれる場合は、作成した時刻値のうち
<parameter>format</parameter> で指定されていない部分と
<literal>!</literal> の左側の部分を
Unix エポックの対応する箇所の値で初期化します。
</para>
<para>
Unix エポックは 1970-01-01 00:00:00 です。
</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>datetime</parameter> パラメータが UNIX タイムスタンプ
(例: <literal>946684800</literal>) だったり、タイムゾーンを含んでいたり
(例: <literal>2010-01-28T15:00:00+02:00</literal>)
する場合は、
<parameter>timezone</parameter> パラメータや現在のタイムゾーンは無視します。
</para>
</note>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
新しい DateTimeImmutable のインスタンスを返します。
&return.falseforfailure;.
</para>
</refsect1>
<refsect1 role="errors">
&reftitle.errors;
<para>
<parameter>datetime</parameter> に NULLバイトが含まれている場合は、
<exceptionname>ValueError</exceptionname> がスローされます。
</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>
<parameter>format</parameter> に指定できる文字に、
<literal>X</literal><literal>x</literal> が追加されました。
</entry>
</row>
<row>
<entry>8.0.21, 8.1.8, 8.2.0</entry>
<entry>
<parameter>datetime</parameter> に NULLバイトが含まれている場合は、
<exceptionname>ValueError</exceptionname> がスローされるようになりました。
これより前のバージョンでは、こうした値は静かに無視されていました。
</entry>
</row>
<row>
<entry>7.3.0</entry>
<entry>
<parameter>format</parameter> に指定できる文字に、
<literal>v</literal> が追加されました。
</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'
);
echo $date->format('c e') . "\n";
$date = DateTimeImmutable::createFromFormat(
DateTimeInterface::RFC3339_EXTENDED,
'2013-10-14T09:00:00.000+02:00'
);
echo $date->format('c e') . "\n";
]]>
</programlisting>
<para>
この例で使われている
<link linkend="datetimeinterface.constants.types">定義済みの定数</link>
は、<classname>DateTimeImmutable</classname>
<link linkend="datetime.format">フォーマット</link> 文字からなる文字列です。
ほとんどの場合、それらのフォーマット文字は 上の <link
linkend="datetimeimmutable.createfromformat.parameters">パラメータ</link>
で定義されている 日付/時刻 の要素とマッチしますが、
カバーしている範囲は狭いです。
</para>
</example>
<example>
<title><function>DateTimeImmutable::createFromFormat</function> の複雑な例</title>
<programlisting role="php">
<![CDATA[
<?php
echo 'Current time: ' . date('Y-m-d H:i:s') . "\n";
$format = 'Y-m-d';
$date = DateTimeImmutable::createFromFormat($format, '2009-02-15');
echo "Format: $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: $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: $format; " . $date->format('Y-m-d H:i:s') . "\n";
$format = '!d';
$date = DateTimeImmutable::createFromFormat($format, '15');
echo "Format: $format; " . $date->format('Y-m-d H:i:s') . "\n";
$format = 'i';
$date = DateTimeImmutable::createFromFormat($format, '15');
echo "Format: $format; " . $date->format('Y-m-d H:i:s') . "\n";
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
Current time: 2022-06-02 15:50:46
Format: Y-m-d; 2009-02-15 15:50:46
Format: Y-m-d H:i:s; 2009-02-15 15:16:17
Format: Y-m-!d H:i:s; 1970-01-15 15:16:17
Format: !d; 1970-01-15 00:00:00
Format: 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桁の数値が必要ですが、
2桁の数値が存在するので、ここでは貪欲に <literal>60</literal> を読み込みます。
</para>
<para>
その後に続く <literal>i</literal><literal>s</literal>
フォーマット文字は、両方2桁の数値が必要です。
つまり、<literal>10</literal> が (フォーマット文字 <literal>i</literal> の) 分として渡されるので、
(フォーマット文字 <literal>s</literal> の) 秒としてパースする十分な桁数が残っていません。
</para>
<para>
配列の <literal>errors</literal> キーの内容が、
この問題を説明しています。
</para>
<para>
さらに、24時間制の時は、
<literal>0</literal>-<literal>24</literal> の範囲であるため、
<literal>60</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
-->