以下も併せてお読みください。
日付時刻の入力書式
以下の関数やメソッドで使われます。
- strtotime
- DateTime::__construct
- DateTimeImmutable::__construct
- DateTime::modify
- DateTimeImmutable::modify
- DateInterval::createFromDateString
書式について詳しく知りたい場合はサポートする日付と時刻の書式を参照してください。特に**相対的な書式**の注意事項には目を通しておくべきです。
ここではマニュアルを見ても分かりづらいであろう「変更される部分」「変更されない部分」を明らかにし、また具体例を中心にピックアップしていきたいと思います。
- タイムゾーンは
php.ini
で既定された値に従います。ここでは現在のタイムゾーンがUTC
または+00:00
に既定されていると仮定します。 - 書式中にタイムゾーンが含まれていた場合、それに従います。
- DateTimeZoneオブジェクトによりタイムゾーンが指定された場合、それに従います。
- 書式中のタイムゾーンとDateTimeZoneオブジェクトが同時に競合した場合、書式中のタイムゾーンが優先されます。
- 表中の
*
は現在値が使用されることを意味します。
絶対指定
指定対象 | 年 | 月 | 日 | 時 | 分 | 秒 | タイムゾーン | 書式 | 注記 |
---|---|---|---|---|---|---|---|---|---|
時刻 | * | * | * | 23 | 00 | 00 | * | 23:00:00 |
|
23.00.00 |
23:00:00.0000000 |
|
|||||||
23.00.00.0000000 | |||||||||
T23:00:00 |
|||||||||
230000 |
6桁 | ||||||||
11 pm |
|||||||||
11:00 PM |
|||||||||
11.00 P.M. |
|||||||||
年月日 | 2015 | 01 | 02 | 00 | 00 | 00 | * | 2015-01-02 |
年は4桁 |
15-1-2 |
非推奨 | ||||||||
2-1-2015 |
年は4桁 | ||||||||
2.1.2015 |
年は4桁 | ||||||||
2.1.15 |
非推奨 | ||||||||
2015/01/02 |
年は4桁 | ||||||||
2015-1-2 |
年は4桁 | ||||||||
1/2/2015 |
年は4桁 | ||||||||
1/2/15 |
非推奨 | ||||||||
2 January 2015 |
|||||||||
2 January 15 |
非推奨 | ||||||||
January 2 2015 |
|||||||||
January 2 15 |
非推奨 | ||||||||
2nd January 2015 |
|||||||||
2 Jan 2015 |
|||||||||
2-Jan 2015 |
|||||||||
2-Jan-2015 |
|||||||||
年月 | 2015 | 01 | 01 | 00 | 00 | 00 | * | 2015-01 |
年は4桁 |
January 2015 | |||||||||
2015 January | |||||||||
Jan 2015 | |||||||||
Jan-2015 | |||||||||
月日 | * | 01 | 02 | 00 | 00 | 00 | * | 01/02 |
|
2 January |
|||||||||
January 2 |
|||||||||
2nd January |
|||||||||
2 Jan |
|||||||||
2-Jan |
|||||||||
Jan 2 |
|||||||||
Jan-2 |
|||||||||
年 | 2015 | * | * | * | * | * | * | 2015 |
4桁 |
月 | * | 01 | * | 00 | 00 | 00 | * | January |
|
Jan |
|||||||||
年月日, 時刻 | 2015 | 02 | 03 | 23 | 03 | 04 | * | 2015-02-03 23:03:04 |
年は4桁 |
2015-02-03T23:03:04 | |||||||||
年, 週番号, 曜日番号 | 2015 | 02 | 03 | 00 | 00 | 00 | * | 2015-W06-2 |
|
2015W062 | |||||||||
年, 週番号 | 2015 | 02 | 01 | 00 | 00 | 00 | * | 2015-W06 |
|
2015W06 | |||||||||
年, 通算日 | 2015 | 02 | 03 | 00 | 00 | 00 | * | 2015.034 |
年は4桁, 通算日は3桁 |
2015034 | |||||||||
タイムスタンプ | 2015 | 02 | 03 | 23 | 03 | 04 | UTC | @1422972184 |
|
タイムゾーン (数値) |
* | * | * | * | * | * | +09:00 | +0900 |
|
+09:00 | |||||||||
GMT+09:00 |
相対指定
意味 | 年 | 月 | 日 | 時 | 分 | 秒 | タイムゾーン | 書式 | 注記 |
---|---|---|---|---|---|---|---|---|---|
現在 | * | * | * | * | * | * | * | now |
コンストラクタの規定値 |
時刻を00:00:00 に |
* | * | * | 00 | 00 | 00 | * | today |
|
midnight |
|||||||||
時刻を12:00:00 に |
* | * | * | 12 | 00 | 00 | * | today |
|
時刻を前日の00:00:00 に |
* | * | -1 | 00 | 00 | 00 | * | yesterday |
|
時刻を翌日の00:00:00 に |
* | * | +1 | 00 | 00 | 00 | * | tomorrow |
|
時刻を18時15分前に | * | * | * | 17 | 45 | 00 | * | front of 18 |
タイムゾーン記述と併用すると12時間ずれるバグがある |
front of 6 pm | |||||||||
時刻を18時15分後に | * | * | * | 18 | 15 | 00 | * | back of 18 |
|
back of 6 pm | |||||||||
時刻を1分前に | * | * | * | * | -1 | * | * | -1 min |
|
-1 mins |
|||||||||
-1 minutes |
|||||||||
1 min ago |
|||||||||
previous mins |
|||||||||
first min ago |
|||||||||
日付を2週間後に | * | * | +14 | * | * | * | * | +2 week |
|
+2 weeks |
|||||||||
2 weeks |
|||||||||
next weeks next week |
|||||||||
second weeks |
weeks は必ず複数形(序数詞+週単位のケースが特例) |
||||||||
日付を月の初日に | * | * | 1 | * | * | * | * | first day of |
of に月を続けると自然言語風らしくなる |
日付を月の末日に | * | * | 特殊 | * | * | * | * | last day of |
|
日付を月の2番目の木曜日に | * | * | 特殊 | 00 | 00 | 00 | * | second Thursday of |
|
日付を月の最後の水曜日に | * | * | 特殊 | 00 | 00 | 00 | * | last Wednesday of |
|
(今日を含む) 次の木曜日 |
* | * | 特殊 | 00 | 00 | 00 | * | Thursday |
|
(今日を含まない) 次の火曜日 |
* | * | 特殊 | 00 | 00 | 00 | * | next Tuesday |
|
(月曜を始まりとする) 来週の月曜日 |
* | * | 特殊 | 00 | 00 | 00 | * | Monday next week |
|
(月曜を始まりとする) 先週の日曜日 |
* | * | 特殊 | 00 | 00 | 00 | * | Sunday previous week |
|
タイムゾーン(名称)をAsia/Tokyo に |
* | * | * | +9 | * | * | Asia/Tokyo | Asia/Tokyo |
|
日付時刻の入力書式定義のための書式
以下のメソッドで使われます。
コンストラクタをそのまま使う際に問題であった解釈の曖昧性を、自分で書式定義することにより解消出来る有用なメソッドです。マニュアルに十分な説明があるので、具体例の紹介は割愛します。
日付時刻の出力書式
以下の関数やメソッドで使われます。
マニュアルに十分な説明があるので、具体例の紹介は割愛します。
時間の入力書式
以下のメソッドで使われます。この書式は他とは大きく見た目が異なりますが、非常にシンプルなので理解に困ることは無いでしょう。
マニュアルに十分な説明があるので、P <*Y><*M><*D|*W> T <*H><*I><*S>
の形に従う通常の書式に関する具体例の紹介は簡便に済ませます。但し、このオブジェクトにはマニュアルに記載されていない隠しプロパティが存在しており、それはDateInterval::createFromDateStringを利用して生成することによってのみ設定することが可能なものです。
PHPバージョン | 隠しプロパティを直接書き換えようとしたときの挙動 |
---|---|
HHVM |
__set() メソッドがコールされ、Undefined property として例外が投げられる |
5.3.27以降 5.4.17以降 5.5.0以降 |
全て 0 が設定される |
5.3.26以前 5.4.16以前 |
意図通りの値が設定される |
上記のとおりPHP言語の開発者サイドから「触るんじゃねーぞ!」みたいな圧力を受けている気がするので、もし可能なバージョンであったとしても自分で書き換えるのはやめておいたほうが良さそうです。
マニュアルに記載されているプロパティ
y
m
d
h
i
s
書式 | y |
m |
d |
h |
i |
s |
---|---|---|---|---|---|---|
P2D |
0 | 0 | 2 | 0 | 0 | 0 |
P2W |
0 | 0 | 14 | 0 | 0 | 0 |
PT2S |
0 | 0 | 0 | 0 | 0 | 2 |
P6YT5M |
6 | 0 | 0 | 0 | 5 | 0 |
この方法で直接負の値を設定することは出来ません。設定するには以下の何れかを採用してください。
$interval = new \DateInterval('P0D');
$interval->i = -1;
$interval->s = -30;
$interval = \DateInterval::createFromDateString('-1 min -30 sec');
invert
0
または1
の値を取る、正負を逆転させるフラグです。以下のメソッドで結果が負になる演算を行った時、負の値をプロパティに代入する代わりにこのフラグがセットされた上で正の値が使われます。
これを手動で有効にすれば負の値を設定したときと同じ効果が得られます。
// 正を負に反転させたものを加算する
$interval = new \DateInterval('P1D');
$interval->invert = 1;
$date = (new \DateTimeImmutable('2015-03-05'))->add($interval);
echo $date->format('Y-m-d') . PHP_EOL; // 2015-03-04
// 負を正に反転させたものを加算する
$interval = \DateInterval::createFromDateString('-1 day');
$interval->invert = 1;
$date = (new \DateTimeImmutable('2015-03-05'))->add($interval);
echo $date->format('Y-m-d') . PHP_EOL; // 2015-03-06
但し、このフラグを正しく扱えるのは以下の加減算に直接関わるメソッドに限られます。
$interval = \DateInterval::createFromDateString('-1 day');
var_dump($interval->d); // int(-1)
var_dump($interval->invert); // int(0)
$a = new \DateTime('2015-02-15');
$b = new \DateTime('2015-02-20');
$negative_interval = \DateInterval::createFromDateString('-1 day');
$inverted_interval = new \DateInterval('P1D');
$inverted_interval->invert = 1;
$inverted_negative_interval = \DateInterval::createFromDateString('-1 day');
$inverted_negative_interval->invert = 1;
// 全て array(0) { }
var_dump(iterator_to_array(new \DatePeriod($b, $negative_interval, $a)));
var_dump(iterator_to_array(new \DatePeriod($b, $inverted_interval, $a)));
var_dump(iterator_to_array(new \DatePeriod($b, $inverted_negative_interval, $a)));
// 全てメモリーリーク
var_dump(iterator_to_array(new \DatePeriod($a, $negative_interval, $b)));
var_dump(iterator_to_array(new \DatePeriod($a, $inverted_interval, $b)));
var_dump(iterator_to_array(new \DatePeriod($a, $inverted_negative_interval, $b)));
一貫性ガン無視な実装ですが、これもまたPHPならではの趣と言えるでしょう。
days
総日数を表します。以下のメソッドで演算を行った時にのみ設定される特別なプロパティとされます。
$a = new \DateTime('2015-02-15');
$b = new \DateTime('2014-02-15');
$interval = $a->diff($b);
var_dump($interval->invert); // int(1)
var_dump($interval->y); // int(1)
var_dump($interval->m); // int(0)
var_dump($interval->d); // int(0)
var_dump($interval->days); // int(365)
マニュアルに記載されていないプロパティ
first_last_day_of
日数が月ごとに再計算されるかどうかを示すフラグです。
do_adjust_special_early関数によって処理されます。
first_last_day_of |
意味 | 書式例 |
---|---|---|
1 |
今月の初日 | first day of |
2 |
翌月の末日 | last day of next month |
weekday
weekday_behavior
have_weekday_relative
曜日を扱うフラグです。
do_adjust_relative関数によって処理されます。
weekday |
weekday_behavior |
have_weekday_relative |
意味 | 書式 |
---|---|---|---|---|
3 |
1 |
1 |
**(今日を含む) **次の木曜日 |
Wednesday |
2 |
1 |
1 |
**(今日を含まない) **次の火曜日 |
next Tuesday |
1 |
2 |
1 |
(月曜を始まりとする) 今週の月曜日 |
Monday this week |
0 |
2 |
1 |
(月曜を始まりとする) 先週の日曜日 |
Sunday previous week |
special_type
special_amount
have_special_relative
特別な処理を行うフラグです。have_weekday_relative
と複合しているものもあります。
do_adjust_special関数によって処理されます。
special_type |
special_amount |
have_special_relative |
意味 | 書式 |
---|---|---|---|---|
1 |
2 |
1 |
2日間隔の平日 | second weekday |
2 |
0 |
1 |
今月の2番目の木曜日 | second Thursday of |
3 |
0 |
1 |
今月の最後の水曜日 | last Wednesday of |
時間の出力書式
以下のメソッドで使われます。この書式は他とはやや見た目が異なりますが、非常にシンプルなので理解に困ることは無いでしょう。PHPを含むさまざまな言語で利用されているprintf
の書式に類似した形式です。
マニュアルに十分な説明があるので、具体例の紹介は割愛します。但し1点だけ注意があります。
$date = new \DateInterval('P0D');
$date->d = -1;
$date->invert = 1;
echo $date->format('%R%d') . PHP_EOL; // --1
echo $date->format('%r%d') . PHP_EOL; // --1
期間の入力書式
以下のメソッドで使われます。
3種類の引数の渡し方がありますが、このうち3番目の、以下に示される$isostr
として利用されます。
public DatePeriod::__construct ( string $isostr [, int $options ] )
ISO8601に従うとありますが、実際には更に以下の制約が付きます。
日付日時に対する制約
- 日付と時刻を両方含む必要があり、デリミタとして
T
が必要である。 - タイムゾーンは
UTC
固定であり、それを意味するZ
がサフィックスとして必要である。
反復回数に対する制約
- 回数にはプレフィックス
R
が必要である。
全体としての制約
以下の何れかのフォーマットに従う必要がある。
開始日時/反復間隔/終了日時
開始日時/終了日時/反復間隔
開始日時/反復間隔/反復回数
反復回数/開始日時/反復間隔
$period = new \DatePeriod('2015-01-01T00:00:00Z/P1D/2016-01-01T00:00:00Z');
var_dump(count(iterator_to_array($period))); // int(365)
$period = new \DatePeriod('2015-01-01T00:00:00Z/P1D/R364');
var_dump(count(iterator_to_array($period))); // int(365)
実際、3つの引数に分けて渡すこともできるので、無理に厳しい制約に従いつつ引数を1つにしなくても特に問題はないでしょう。