エス技研

WordPress、CakePHP、PHP、baserCMSなどの Web系システムを中心に情報を提供します!


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の基本形:現在日時を取得

 

 
出力した結果は下記のようになります。
 

 
現在日時を取得する際は「DateTimeImmutable()」のパラメータに「now」を指定していますが、パラメータがない場合は「now」が指定されたものとして現在日時を取得します。
 
 

DateTimeImmutableで取得した日時のオブジェクトをmodifyを利用して希望の日時を取得する

 
「DateTimeImmutable」で取得した日時のオブジェクトを「modify」を利用して希望の日時を取得する方法は下記となります。
 

 
上記の方法で現在日時を基準として、「今月末の日付」を取得することができます。
 
 
「今月末の日付」を取得する場合は「last day of this month」を指定しますが、「今月の初日」の場合は「first day of this month」を指定します。
 
その他、多様な指定方法がありますが、指定方法は CakePHPと同じですので、下記の記事を参照してください。
CakePHP4のFrozenDateで1ヵ月前、先月、今月1日、来月末の日付などを算出する方法
 
 

「現在日時」を基準に「DateTimeImmutable」を使用する場合は直接指定する方法もある

 
前項では、「DateTimeImmutable」で取得した日時のオブジェクトをmodifyを利用して変換する方法を取りました。
 
しかし、「現在日時」を基準に今月末が分かればいい、という場合は下記のように「DateTimeImmutable」に直接指定する方法もあります。
 

 
 

指定した「日時」を基準に「DateTimeImmutable」+「modify」を使用する方法もある

 
前項では「現在日時」を基準に処理する方法でしたが、指定した「日時」を基準にする場合は、最初に指定した日時のオブジェクトを作成し、それに対して modifyを指定する方法があります。
 

 
 
ちなみに、上記も下記のように 1行で処理することもできます。
 

 
 

日時のオブジェクトは「format()」を使用して表示

 
最後になりましたが、日時のオブジェクトを表示する場合は、「format()」を使用して表示したいフォーマットに変換することができます。
 

 
 
ちなみに「$today」に値が入っていない場合はエラーとなりますので、「$today」に値が入っていない可能性がある場合は、下記のように値があるか否かの判定をする処理を追加しておくことをオススメします。
 

 
 
フォーマットとして指定するパラメータの詳細は下記を参照してください。
PHPオフィシャル DateTime::format
https://www.php.net/manual/ja/datetime.format.php
 
 

DateTimeImmutable と DateTime の違い

 
PHPには、日時のオブジェクトを生成する関数として「DateTimeImmutable」と「DateTime」が用意されています。
どちらも同じようなメソッドが利用できて、同じように使用することができます。
 
違いは「DateTimeImmutable」には「Immutable(不変)」と付いているように、生成されたオブジェクトは「不変」ということです。
 
その違いが分かる具体的な処理は「modify」を使用したときに現れます。
 
 
「DateTimeImmutable」を使用した場合

 
 
「DateTime」を使用した場合

 
上記のように、「modify('+1 day')」を実行すると、「DateTimeImmutable」の方の「$dateImmutable」の日時は変更されませんが、「DateTime」の方の「$dateDateTime」の日時は「+1 day」されて、「$dateDateTime2」と同じ値になっています。
 
つまり、変わる「DateTime」と、不変の「DateTimeImmutable」というワケです。
 
この仕様を理解したうえで、活用するために「DateTime」を使用するのであれば問題ないですが、無用なバグ混入を避けるためには「DateTimeImmutable」を使っておく方が無難だと思いますね。
特に複数人で開発を行う場合は、全員にこの理解が求められますので。
 
 

PHPでは月末に対して実行する「+1 month」は想定の結果にならない場合がある

 
PHPでは月末日を基準として「+1 month」を実行したとき、想定した結果にならない場合があるようです。
これはバグではなく、PHPの仕様だ!ということのようで、PHPで日付を扱う場合はしっかりと認識をしておく必要がある仕様かと思います。
 
具体的には以下の通りです。
 

 
上記を実行すると、以下のようになります。
 

 
 
この PHPの日付の処理については、下記に詳細な仕様の説明と、対応策を書いていますので、併せて参考にしてください。
PHPで月末から1ヶ月後「+1 month」を算出すると想定する日付にならない場合がある

 - PHP・Smarty・ECCUBE

GoogleAdwords

GoogleAdwords

最後までお読みいただきましてありがとうございます。
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!

Message

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

下記の空欄を埋めてください。 * Time limit is exhausted. Please reload CAPTCHA.

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

※入力いただいたコメントは管理者の承認後に掲載されます。

  関連記事

数値がMySQLのint(11)に保存できない!PHPの変数が本当にint型か確認!
数値がMySQLのint(11)に保存できない!PHPの変数が本当にint型か確認!

PHPでintegerとdoubleが混在するような計算をする場合は要注意!計算結果が整数値であっても途中で使用する変数にdoubleの値が入っているときは計算結果がintegerではない場合があります。

sleepの秒指定は整数のみなので1.5秒はsleep、usleepを組み合わせる
sleepの秒指定は整数のみなので1.5秒はsleep、usleepを組み合わせる

PHPのプログラム処理を遅延させる「sleep()」は整数秒単位。「usleep()」は1秒未満のマイクロ秒単位。では「1.5」秒はどう表現するのか。「sleep()」「usleep()」を組み合わせる。その解説。

ECCUBEの注文完了画面注文番号と商品情報を編集するCRITEO(クリテオ)タグを編集

ECCUBEの注文完了画面にクリテオのタグを編集する方法を紹介。標準機能では完了画面に注文IDや購入商品の情報を渡さないため改修が必要です。

ECCUBEの管理画面のSSL設定をインストール後に変更する方法

ECCUBEをインストールした後から管理画面のSSL設定を変更する方法を解説します。config.phpファイルのHTTPS_URLとADMIN_FORCE_SSLの値を変更すればOK。

フォルダを指定してファイルのパーミッションを変更するプログラム

フォームからフォルダ、パーミッションを指定しパーミッションを変更するサンプルプログラムの解説です。

PHPで APIにアクセスする際などに使用する cURLのサンプルプログラム
PHPで APIにアクセスする際などに使用する cURLのサンプルプログラム

PHPのcURLを使用して各種APIにアクセスするサンプルプログラムを作成し、その処理を解説。カオナビAPIのみならず、他の多くのAPIにアクセスする際にも使用できる。

路線・駅検索をPHPで実装する方法解説。GoogleMapsの緯度経度から計算し検索
路線・駅検索をPHPで実装する方法解説。GoogleMapsの緯度経度から計算し検索

路線・駅検索の仕組みの構築は大変。登録する側も最寄り駅が多い場合は大変。なので簡易に実装するため緯度経度に基づき直線距離を計算する処理を考案して実装して、その処理を解説。

JSON形式の値を配列形式に変換・PHPでは json_decode()、json_encode()
JSON形式の値を配列形式に変換・PHPでは json_decode()、json_encode()

JSONとは「JavaScript Object Notation」の略でテキストベースのデータフォーマット。JSONの値をPHPで配列に変換するWebツールの紹介とその処理「json_encode()」「json_decode()」関数の解説。

路線・駅検索のために緯度経度からPHPで簡易的に距離を計算する処理解説
路線・駅検索のために緯度経度からPHPで2点間の距離を計算する処理解説

路線・駅検索の仕組みの構築は大変。それを簡易に実装するために緯度経度を元に距離計算をする仕組みを考案。まずは2点間の距離を計算する仕組みを解説し、距離計算にまつわる関連技術も紹介。

QRコード作成ライブラリ「cakePHP-QR-Code-Helper」をPHPで使うカスタマイズ
QRコード作成ライブラリ「cakePHP-QR-Code-Helper」をPHPで使うカスタマイズ

CakePHP2用のQRコード作成ライブラリ「cakePHP-QR-Code-Helper」をプレーンのPHPでも使うためのカスタマイズ方法を解説。1ファイルを設置するだけでQRコードが作れるため使い勝手がいい。