PHPで1ヵ月前、先月、今月1日、来月末の日付などの算出はDateTimeImmutableを使う
PHPで1ヵ月前、先月、今月1日、来月末の日付などの算出はDateTimeImmutableを使う
プログラムを作成する際に、下記のような特定の条件に基づいて日付を算出する場合があるかと思います。
・先月の 1日
・来月の月末
・1ヵ月前の日付
「CakePHP4のFrozenDateで1ヵ月前、先月、今月1日、来月末の日付などを算出する方法」
上記の記事では CakePHP4での処理方法を紹介しました。
CakePHP4には「FrozenTime」「FrozenDate」という便利な関数が用意されていますので、これを使用すると簡単に算出することができます、と。
この記事では、CakePHPで用意された関数ではなく、PHP自体の関数ではどう対応するのか、それを紹介します。
ずばり、PHPでは「DateTimeImmutable」を使用します。
PHP公式 DateTimeImmutable
https://www.php.net/manual/ja/datetimeimmutable.construct.php
DateTimeImmutableは日付のオブジェクトを生成する
「DateTimeImmutable」は日付のオブジェクトを生成します。
DateTimeImmutableの基本形:現在日時を取得
|
1 2 3 4 5 |
// 現在日時を取得 $dateImmutable = new DateTimeImmutable("now"); // 取得した時刻を出力 var_export($dateImmutable); |
出力した結果は下記のようになります。
|
1 2 3 4 5 |
DateTimeImmutable::__set_state(array( 'date' => '2024-09-01 12:12:12.345678', 'timezone_type' => 3, 'timezone' => 'Asia/Tokyo', )) |
現在日時を取得する際は「DateTimeImmutable()」のパラメータに「now」を指定していますが、パラメータがない場合は「now」が指定されたものとして現在日時を取得します。
DateTimeImmutableで取得した日時のオブジェクトをmodifyを利用して希望の日時を取得する
「DateTimeImmutable」で取得した日時のオブジェクトを「modify」を利用して希望の日時を取得する方法は下記となります。
|
1 2 3 4 5 6 |
// 現在日時を取得 $dateImmutable = new DateTimeImmutable("now"); // modify()を利用して希望の日時を取得 // 今月末の日付(「last day」で月末の日付、「this month」で今月) $dateImmutable2 = $dateImmutable->modify('last day of this month'); |
上記の方法で現在日時を基準として、「今月末の日付」を取得することができます。
「今月末の日付」を取得する場合は「last day of this month」を指定しますが、「今月の初日」の場合は「first day of this month」を指定します。
その他、多様な指定方法がありますが、指定方法は CakePHPと同じですので、下記の記事を参照してください。
「CakePHP4のFrozenDateで1ヵ月前、先月、今月1日、来月末の日付などを算出する方法」
「現在日時」を基準に「DateTimeImmutable」を使用する場合は直接指定する方法もある
前項では、「DateTimeImmutable」で取得した日時のオブジェクトをmodifyを利用して変換する方法を取りました。
しかし、「現在日時」を基準に今月末が分かればいい、という場合は下記のように「DateTimeImmutable」に直接指定する方法もあります。
|
1 2 |
// 「今月末の日付」を指定 $dateImmutable = new DateTimeImmutable("last day of this month"); |
指定した「日時」を基準に「DateTimeImmutable」+「modify」を使用する方法もある
前項では「現在日時」を基準に処理する方法でしたが、指定した「日時」を基準にする場合は、最初に指定した日時のオブジェクトを作成し、それに対して modifyを指定する方法があります。
|
1 2 3 4 5 |
// 「今月末の日付」を指定 $dateImmutable = new DateTimeImmutable("2000-02-01"); // 「1日後」を指定 $dateImmutable2 = $dateImmutable->modify('+1 day'); |
ちなみに、上記も下記のように 1行で処理することもできます。
|
1 |
$dateImmutable2 = new DateTimeImmutable("2000-02-01 +1 day"); |
日時のオブジェクトは「format()」を使用して表示
最後になりましたが、日時のオブジェクトを表示する場合は、「format()」を使用して表示したいフォーマットに変換することができます。
|
1 2 3 4 5 6 |
// 現在日時をオブジェクトとして生成 $today = new DateTimeImmutable(); // フォーマットを整えて出力 echo $today->format('Y-m-d'); echo $today->format('Y年m月d日 H:i:s'); |
ちなみに「$today」に値が入っていない場合はエラーとなりますので、「$today」に値が入っていない可能性がある場合は、下記のように値があるか否かの判定をする処理を追加しておくことをオススメします。
|
1 |
echo $today ? $today->format('Y年m月d日 H:i:s') : ""; |
フォーマットとして指定するパラメータの詳細は下記を参照してください。
PHPオフィシャル DateTime::format
https://www.php.net/manual/ja/datetime.format.php
DateTimeImmutable と DateTime の違い
PHPには、日時のオブジェクトを生成する関数として「DateTimeImmutable」と「DateTime」が用意されています。
どちらも同じようなメソッドが利用できて、同じように使用することができます。
違いは「DateTimeImmutable」には「Immutable(不変)」と付いているように、生成されたオブジェクトは「不変」ということです。
その違いが分かる具体的な処理は「modify」を使用したときに現れます。
「DateTimeImmutable」を使用した場合
|
1 2 3 4 5 6 7 8 9 10 |
// 「2000-02-01」のオブジェクトを生成 $dateImmutable = new DateTimeImmutable('2000-02-01'); var_export($dateImmutable); // 2000-02-01 echo " <br>"; $dateImmutable2 = $dateImmutable->modify('+1 day'); var_export($dateImmutable); // 2000-02-01 echo " <br>"; var_export($dateImmutable2); // 2000-02-02 echo " <br>"; |
「DateTime」を使用した場合
|
1 2 3 4 5 6 7 8 9 10 |
// 「2000-02-01」のオブジェクトを生成 $dateDateTime = new DateTime('2000-02-01'); var_export($dateDateTime); // 2000-02-01 echo " <br>"; $dateDateTime2 = $dateDateTime->modify('+1 day'); var_export($dateDateTime); // 2000-02-02 echo " <br>"; var_export($dateDateTime2); // 2000-02-02 echo " <br>"; |
上記のように、「modify('+1 day')」を実行すると、「DateTimeImmutable」の方の「$dateImmutable」の日時は変更されませんが、「DateTime」の方の「$dateDateTime」の日時は「+1 day」されて、「$dateDateTime2」と同じ値になっています。
つまり、変わる「DateTime」と、不変の「DateTimeImmutable」というワケです。
この仕様を理解したうえで、活用するために「DateTime」を使用するのであれば問題ないですが、無用なバグ混入を避けるためには「DateTimeImmutable」を使っておく方が無難だと思いますね。
特に複数人で開発を行う場合は、全員にこの理解が求められますので。
PHPでは月末に対して実行する「+1 month」は想定の結果にならない場合がある
PHPでは月末日を基準として「+1 month」を実行したとき、想定した結果にならない場合があるようです。
これはバグではなく、PHPの仕様だ!ということのようで、PHPで日付を扱う場合はしっかりと認識をしておく必要がある仕様かと思います。
具体的には以下の通りです。
|
1 2 3 4 5 6 7 |
$today = new DateTimeImmutable("2024-01-31"); var_export($today); var_export($today->modify('+1 month')); var_export($today->modify('+2 month')); var_export($today->modify('+3 month')); var_export($today->modify('+4 month')); |
上記を実行すると、以下のようになります。
|
1 2 3 4 5 |
'date' => '2024-01-31 00:00:00.000000' // today 'date' => '2024-03-02 00:00:00.000000' // +1 month 'date' => '2024-03-31 00:00:00.000000' // +2 month 'date' => '2024-05-01 00:00:00.000000' // +3 month 'date' => '2024-05-31 00:00:00.000000' // +4 month |
この PHPの日付の処理については、下記に詳細な仕様の説明と、対応策を書いていますので、併せて参考にしてください。
「PHPで月末から1ヶ月後「+1 month」を算出すると想定する日付にならない場合がある」
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
-
ECCUBEでアップロードできない。upload_max_filesizeを設定する場所
テンプレートをアップロードする際に発生するエラー「テンプレートファイルがアップロードされていません」の対処方法。これはファイル容量の制限に引っかかっています。
-
-
WindowsのXAMPPのPHPではstrptimeは使用不可。代替はdate_parse_from_formatを使う
strptimeはWindowsのPHPには未実装。LinuxとMacで挙動が異なる。PHP8.1で非推奨になる。なので日付のチェックはdate_parse_from_formatを使おう。使い方を詳細解説。
-
-
QRコード(二次元バーコード)作成サービスを公開
QRコード(二次元バーコード)を生成するサービス。QRコードにする文字列を入力するだけで QRコードが簡単に作れる。オプションとして、画像サイズ、余白サイズ、エラー訂正レベルがある。
-
-
CentOS6、7のPHPを5.3から5.6、7.0、7.1にバージョンアップする手順の解説
CentOS6系、7系のPHPバージョンを5.3から5.6、7.0、7.1にアップする作業手順と解説。yum updateコマンドを使い作業時間は約10分。コマンドの解説や引数の意味なども解説しているので役に立つはず。
-
-
ECCUBEのポイント設定、ポイント付与率を一括で変更する方法解説
ECCUBEの商品個別に設定してあるポイントを一括で変更する方法を解説。ECCUBEには商品個別のポイントを一括して変更する機能がありません。SQLを作成して一括置換!
-
-
PHPで月末から1ヶ月後「+1 month」を算出すると想定する日付にならない場合がある
PHPでは月末の1ヶ月後が想定した日付にならない場合がある。原因はバグではなくPHPの1ヶ月後の定義によるもの。なので必要とする日付を定義しそれに合わせてDateTime、modifyを使用して算出方法を解説している。
-
-
複数銘柄を指定して株価チャートを一覧するツール公開
入力銘柄の5日間、3か月間、6か月間、1年間、2年間の株価チャートを一覧表示しますのでチャートで売買判断をするのに最適です。
-
-
ECCUBE mtb_constants initパラメータ設定の項目を追加する方法
ECCUBEのパラメータ設定で設定できる項目を追加する方法を説明します。
-
-
PHPのデバッグで使う print_r、var_dump、var_exportの動作の違い
PHPのデバッグ等で変数や配列の中身を確認するために使用する関数print_r、var_dump、var_exportの動作の違い、仕様の違いについて確認した。var_exportがオススメ。
-
-
Basic認証の.htaccess、.htpasswd生成ツールと解説
Basic認証を設定する際に必要となる.htaccess、.htpasswdファイルを生成するツール。ID、PASS、.htpasswdへのパスを入力することで編集する情報を生成します。