PHP 8.2.0 Beta 3 available for testing

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

書式を文字列で渡します。以下の書式オプションを参照ください。 大半は、date() で使える文字と同じです。

全てのフィールドは現在の日付/時刻で初期化されます。 ほとんどの場合、これらの値を "ゼロ" (Unix タイムのエポック 1970-01-01 00:00:00 UTC) でリセットしたいはずです。 これは、format の最初の文字に ! を入れるか、 最後の文字に | を入れることで実現できます。 詳細な情報は、以下で示すそれぞれの文字に関するドキュメントを参照下さい。

フォーマットの解釈は左から右に行われます。 これは、フォーマット文字が現れる順番が結果に影響する場合があるということです。 たとえば z(1年における何番目の日か) の場合、 Yy を使って年が既にパースされた後に使わなければなりません。

数値の解釈に使われる文字については、広範な値が許されています。 これには、論理的に許される範囲以上のものも含みます。 たとえば、d (ある月における何番目の日か) の場合、 00 から 99 までの値が許されています。これに対する唯一の制約は、桁数のみです。 範囲外の値が指定された場合、 日付/時刻のパーサーのオーバーフローの仕組みが使われます。 オーバーフローのふるまいについては、 後にいくつかのサンプルを示します。

format パラメータに渡せる文字
format 文字 説明 取りうる値の例
--- ---
d および j 2桁の日付。先頭のゼロを含むものと含まないもの 01 から 31 あるいは 1 から 31 (その月の日数分以上の2桁の数値も指定可能ですが、 その月はオーバーフローします。 たとえば January において 33 を指定した場合、 February 2nd という意味になります)
D および l 曜日を表す文字列 Mon から Sun あるいは Sunday から Saturday。 指定された曜日が、パースされた(またはデフォルトの)日付と異なっていた場合、 指定された曜日の 次の 日にオーバーフローします。詳細は後に示すサンプルを参照ください。
S 日付の後につける英語の接尾辞。二文字。処理中には無視されます。 stndrd あるいは th
z 年始からの通算日数 (最初は 0)。 Y または y の後に続けて置かなければいけません。 0 から 365 (1年の日数分以上の3桁の数値も指定可能ですが、 その年はオーバーフローします。 たとえば 2022年において 366 を指定した場合は、 January 2nd, 2023 という意味になります)
--- ---
F および M 月を表す文字列。January あるいは Sept など January から December あるいは Jan から Dec
m および n 月を表す数値。先頭のゼロを含むものと含まないもの 01 から 12 あるいは 1 から 12 (12 以上の2桁の数値も指定可能ですが、 その年についてはオーバーフローします。 たとえば 13 の場合は、 翌年の1月という意味になります)
--- ---
X および x 年の数値表現。19桁まで指定可能。オプションで +- を先頭に指定可能です。 例: 0055, 787, 1999, -2003, +10191
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 以上の2桁の数値も指定可能ですが、 日の指定がオーバーフローします。 たとえば 14 の場合は、 次の午前/午後の 02 時という意味になります)
G および H 24 時間制での時間。先頭のゼロを含むものと含まないもの 0 から 23、あるいは 00 から 23 (24 より大きな、2桁の値も指定可能ですが、 この場合、日の指定がオーバーフローします。 たとえば、26 は翌日の 02:00 という意味になります)
i 分。先頭のゼロを含む 00 から 59 (59 以上の2桁の数値も指定可能ですが、 次の1時間にオーバーフローします。 たとえば 66 の場合は、 次の1時間の :06 という意味になります)
s 秒。先頭のゼロを含む 00 から 59 (59 以上の2桁の数値も指定可能ですが、 次の分にオーバーフローします。 たとえば 90 の場合は、 次の分の :30 という意味になります)
v ミリ秒 (最大 3桁) 例: 12 (0.12 秒という意味), 345 (0.345 秒という意味)
u マイクロ秒 (最大 6 桁) 例: 45 (0.45 秒という意味), 654321 (0.654321 秒という意味)
タイムゾーン --- ---
eOP および T タイムゾーン識別子、UTC からの時差 (時間単位)、 UTC からの時差 (コロン区切りでの時間と分)、そしてタイムゾーンの短縮形 例: UTCGMTAtlantic/Azores+0200+02:00ESTMDT
完全な日付/時刻 --- ---
U Unix エポック (January 1 1970 00:00:00 GMT) からの経過秒数 例: 1292177455
空白および区切り --- ---
(空白) 空白 1 文字あるいはタブ 1 文字 例:
# 次の区切り文字のいずれか: ;, :, /, ., ,, -, (, ) 例: /
;, :, /, ., ,, -, (, ) 指定した文字 例: -
? ランダムなバイト 例: ^ (UTF-8 文字の場合は複数の ? が必要になるでしょう。この場合、おそらく * を使うと要望が満たせるはずです)
* 次の区切り文字あるいは数字までのランダムなバイト列 例: Y-*-d の中の * は、文字列 2009-aWord-08 の中の aWord にマッチします
! すべてのフィールド (年、月、日、時、分、秒、マイクロ秒およびタイムゾーン情報) を ゼロ相当の値 (時、分、秒、マイクロ秒については 0。 月、日については 1。 年については 1970。 タイムゾーンについては UTC) にリセットします。 ! がなければ、すべてのフィールドは現在の日時に設定されます。
| まだパースされていないすべてのフィールド (年、月、日、時、分、秒、マイクロ秒およびタイムゾーン情報) を ゼロ相当の値にリセットします。 Y-m-d| は、文字列をパースした結果から年月日を設定し 時分秒には 0 を設定します。
+ この文字があると、文字列のそれ以降のデータではエラーが発生せず、 かわりに警告を発生させる それ以降のデータが存在したかどうかを調べるには DateTime::getLastErrors() を使います。

書式文字列の中に解釈不能な文字が含まれていると処理は失敗し、 戻り値にはエラーメッセージが付加されます。エラーメッセージを調べるには DateTime::getLastErrors() を使います。

format にリテラル文字を含めるには、 バックスラッシュ (\) でエスケープする必要があります。

format に文字 ! が含まれない場合は、作成した時刻値のうち format で指定されていない部分を 現在のシステム時刻で初期化します。

format に文字 ! が含まれる場合は、作成した時刻値のうち format で指定されていない部分と ! の左側の部分を Unix エポックの対応する箇所の値で初期化します。

Unix エポックは 1970-01-01 00:00:00 です。

datetime

時刻を表す文字列。

timezone

指定したいタイムゾーンを表す DateTimeZone オブジェクト。

timezone を省略されるか、または null の場合、 かつ datetime にタイムゾーンが含まれない場合は、 現在のタイムゾーンを使います。

注意:

datetime パラメータが UNIX タイムスタンプ (例: 946684800) だったり、タイムゾーンを含んでいたり (例: 2010-01-28T15:00:00+02:00) する場合は、 timezone パラメータや現在のタイムゾーンは無視します。

戻り値

新しい DateTimeImmutable のインスタンスを返します。 失敗した場合に false を返します.

変更履歴

バージョン 説明
8.2.0 format に指定できる文字に、 Xx が追加されました。
7.3.0 format に指定できる文字に、 v が追加されました。

例1 DateTimeImmutable::createFromFormat() の例

オブジェクト指向型

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

例2 DateTimeImmutable::createFromFormat() の複雑な例

<?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";
?>

上の例の出力は、 たとえば以下のようになります。

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

例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) {
  }
}

参考

add a note

User Contributed Notes

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