【PHP】DateTimeオブジェクトの使い方!日付操作や設定の仕方を徹底解説!
この記事からわかること
- PHPでの日付操作の仕方
- DateTimeオブジェクトの使い方と設定方法
- タイムゾーンの設定方法
- 日付に関するメソッドの種類
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
phpで操作できる情報のなかに、日付や時刻があります。
現在の日付を表示したり、指定した時刻との差分を求めたり、Webサイトを作る上で何かと絡んでくる日付や時刻。
今回は日付操作できるDateTimeオブジェクトについてまとめていきたいと思います。
タイムゾーンを設定する
まずDateTimeオブジェクトを使うにはタイムゾーンの設定をしないといけません。
タイムゾーンの設定とは取得したい時刻の国を設定するということです。
とはいえ日本なら東京だし、外国ならその国の時刻に合わせることが1番多いと思います。
タイムゾーンの指定をしないとデフォルトは「UTC(Universal Time Coordinated:協定世界時間)」になっています。
東京の現在時刻が2024/10/06 19:11:35
の時、UTCでの時刻は2024/10/06 10:11:35
になります。日本から見ると少しズレがあるのでタイムゾーンは適切に設定するべきなのです。
そんなタイムゾーンの設定方法は3種類あります。
タイムゾーンの設定方法
- php.iniで設定する
- スクリプト内で関数を使い設定する
- インスタンス化するタイミングで指定する
php.iniでの設定方法
php.iniはphpの初期設定ファイルのことです。初期設定ファイルにはあらかじめ色々な設定が決められています。その設定のdate.timezoneパラメータ
を変更することで一括して変更することができます。
php.iniの設定を変更することでいちいちDateTimeオブジェクトを使う度にタイムゾーンを指定しなくても良くなるので非常に楽です。
しかしphp.iniファイルをいじることになるので記述には注意が必要です。
設定方法はphp.iniファイルのこの部分を変更するだけです。
ファイルにもよりますが、このようにコメントアウトされていたり、何も設定されていなかったりするので、コメントアウトを外し、「Europe/Berlin」のところを「Asia/Tokyo」に変更すればOKです!
date.timezone = "Asia/Tokyo"
php.iniの場所ですが「phpinfo」に適応されているphp.iniファイルのパスが乗っています。
MAMPであれば「web start」で開いたページの「Tools」>「phpinfo」をクリックすると適応されているphp.iniのパスが記載されています。
date_default_timezone_set関数でセットする
2つ目の方法はスクリプト内(phpファイルの中)で動的にセットする方法です。
セットするのはdate_default_timezone_set関数
の役割です。
date_default_timezone_set('Asia/Tokyo');
DateTimeオブジェクトを使用する前にこの関数でセットすることでそのスクリプト内のみ、タイムゾーンを変更することができます。
一括で変更するわけではないのでスクリプト毎に設定しないといけないですが、臨機応変に設定できるのがメリットでもあります。
インスタンス化時にDateTimeZoneオブジェクトで設定
3つ目の方法はインスタンス化時の引数にDateTimeZoneオブジェクトを指定して設定する方法です。
$tokyo = new DateTime(null, new DateTimeZone('Asia/Tokyo'));
この方法だとインスタンス化したオブジェクト変数毎に設定できるので同じファイル内で複数インスタンス化するときに便利です。
DateTimeクラスの説明は後述しますので今はこの方法でもタイムゾーンを設定できるのだなと思ってもらえれば大丈夫です。
タイムゾーンの値
すでに何個か紹介してしまっていますが、タイムゾーンの値として指定できるのはあらかじめ決められた値のみです。使いそうなタイムゾーンの値だけ記載しておきます。
タイムゾーンに設定できる値
タイムゾーンの値 | 国 |
---|---|
Asia/Tokyo | 日本/東京 |
America/Toronto | アメリカ/トロント |
UTC | UTC:協定世界時間 |
Pacific/Guam | 太平洋/グアム |
Europe/London | ヨーロッパ/ロンドン |
他にもたくさんあるのでphpのタイムゾーンマニュアルからご覧ください。
現在のタイムゾーンの取得方法
php.iniファイルにタイムゾーンに何が設定されているかを確認できる方法を2つご紹介します。
date_default_timezone_get関数
echo date_default_timezone_get(); // 結果:php.iniに設定されているタイムゾーン
1つ目はdate_default_timezone_get関数
を使った方法です。この関数は実行しているスクリプト内に設定されているタイムゾーンの値を取得してくれます。事前にセットしていればその値になりますし、あくまで現在スクリプト内に設定されているタイムゾーンを返す点に注意してください。
getTimezoneメソッド
もう1つはDateTimeオブジェクトのメソッドで取得する方法です。getTimezoneメソッド
はDateTimeオブジェクトのメンバ関数(メソッド)の1つでそのオブジェクトのタイムゾーンを取得することができます。
戻り値はDateTimeZoneオブジェクトになるので注意してください。
$now = new DateTime(null, new DateTimeZone('Asia/Tokyo'));
$tz = $now->getTimezone(); // DateTimeZoneオブジェクトを格納
echo $tz->getName(); // タイムゾーン名を取得
これでようやく初期設定のあれこれが完了しました。タイムゾーンを設定するだけですが色々なパターンがあるのでだいぶややこしいですね...笑
ここからは実際にDateTimeオブジェクトの使い方をまとめていきたいと思います。
DateTimeオブジェクトの使い方
まずはDateTimeオブジェクトを扱うに当たっての流れを確認してみます。
DateTimeオブジェクトを使う流れ
- タイムゾーンを設定
- インスタンス化(変数に格納)
- オブジェクト変数に対してメソッドを指定したり操作を行う
タイムゾーンの設定はできたのでまずはインスタンス化をしていきます。インスタンス化とはクラスの複製を作って変数の中に格納することを指します。これでこの変数はオブジェクト変数となり、メソッドやプロパティを実行できるようになります。
関連記事:【PHP】class(クラス)の使い方とは?変数やメソッド、インスタンスの意味
$date = new DateTime(); // インスタンス化
引数に指定できるのは2つ、日付や時刻の文字列とDateTimeZoneオブジェクトです。
new DateTime(string $now [,DateTimeZone $tz]);
先程のように引数に何も指定しなければ現在時刻のDateTimeオブジェクトがインスタンス化され、引数に日時の文字列を指定すればその日時のDateTimeオブジェクトがインスタンス化されます。
$now = new DateTime(); // 引数なし
echo $now->format('Y/m/d H:i:s'); // 結果:現在の日付/時刻
$past = new DateTime('2021/3/10 11:12:40'); // 過去の日付を指定
echo $past ->format('Y/m/d H:i:s'); // 結果:過去の日付/時刻
タイムゾーンを指定したいかつ現在の日時をインスタンス化したい時は第1引数にnull
を指定します。第2引数を指定したい時に第1引数は省略できないので注意が必要です。
$now = new DateTime(null, new DateTimeZone('Asia/Tokyo'));
DateTimeオブジェクトでできること
- 現在の日付/時刻を取得
- フォーマットを自由に変更可能
- 現在と指定日の差分を取得
- 日の出時間を計算して取得
現在の日付や時刻の取得方法はタイムゾーンを指定してインスタンス化するだけです。
ではそれどのように画面に表示させるのかを見ていきたいと思います。
echo
やprint
を使ってそのまま表示しようとしてもうまくいきません。まずはどのような形式で表示するかを指定しなければなりません。
formatメソッドで表示させる
formatメソッド
はDateTimeオブジェクトの日付/時刻を任意の形式に変換して出力するメソッドです。
何度かすでに登場しましたがformatの引数を一定のルールさえ守って自由に変えることで自在に整形することができます。
$past = new DateTime('2021/3/10 11:12:40');
echo $past->format('Y/m/d H:i:s');
// 結果:2021/03/10 11:12:40
echo $past->format('Y-m-d H時i分s秒');
// 結果:2021-03-10 11時12分40秒
echo $past->format('今日はl、H時間とi分、s秒たったよ');
// 結果:今日はWednesday、11時間と12分、40秒たったよ
formatメソッドは「format文字」や「記述子」と呼ばれる「Y」や「m」などで月日や時刻の形式を指定できます。
それ以外の文字は自由に記載しても大丈夫なので好きな形式を指定してあげましょう!
代表的なものをあげておきます。
format文字 | 意味 | 値 |
---|---|---|
Y | 年(4桁) | 2021 |
y | 年(2桁) | 21 |
m | 月 | 01〜12 |
n | 月 | 1〜12 |
d | 日 | 01〜31 |
j | 日 | 1〜31 |
H/h | 時間(24時間)/時間(12時間) | 01〜23/01〜12 |
G/g | 時間(24時間)/時間(12時間) | 1〜23/1〜12 |
i | 分 | 00〜59 |
s | 秒 | 00〜59 |
l | 曜日 | Monday〜Sunday |
format文字はまだまだありますので詳しくはphpのformatマニュアルをご覧ください
日付/時間の差分を取得する
DateTimeオブジェクトを2個インスタンス化し、diffメソッド
を使うことで暗算しにくい日付や時刻の差を計算することができます。
戻り値は日付文字列ではなくDateIntervalオブジェクトになるので注意してください。
例えば私がこのサイトを作成した日からこの記事を書いた日の差分を求めるなら以下の通りになります。
date_default_timezone_set('Asia/Tokyo');
$start = new DateTime('2021/8/29');// サイト作成日
$now = new DateTime('2021/10/6');// 記事作成日
$interval = $start->diff($now,true);// 差分を求めて格納
echo $interval->format('%mヶ月と%d日経過')
// 結果:1ヶ月と7日経過
DateIntervalオブジェクトのformatメソッド
では仕組み自体は同じですがformat文字が異なってきます。
format文字 | 意味 | 値 |
---|---|---|
%Y/%y | 年 | 01/1 |
%M/%m | 月 | 06/6 |
%D/%d | 日 | 08/8 |
%H/%h | 時間 | 09/9 |
%I/%i | 分 | 01/1 |
%S/%s | 秒 | 07/7 |
%a | 総日数 | - |
%を前に記述したり、指定するアルファベットも異なるので注意が必要です。
日の出時間を取得する
面白い機能にdate_sunrise関数
で指定した場所の日の出時間を取得することができます。
場所の指定は緯度と経緯で指定します。例えば日本/東京なら北緯36度、東経140度の位置にあります。東京はUTCと9時間の時差があるので時差に「9」を指定します。
date_sunrise($timestamp,フォーマット,緯度,経緯,太陽との角度,UTCとの時差);
echo date_sunrise(time(),SUNFUNCS_RET_STRING,36,140,90,9);
// 今日の東京の日の出時間
- $timestamp:タイムスタンプで指定「time()」
- フォーマット:「SUNFUNCS_RET_STRING」で「07:23」形式の文字列で表示
- 北緯:正の値で北緯を指定、南緯は負の数で指定
- 経緯:正の値で東経を指定、西経は負の数で指定
- 太陽との角度:90°=日の出時刻,96°=薄明かり
- UTCとの時差:UTCとの時差を1時間単位で指定
日付や時刻を操作するメソッド
インスタンス化したDateTimeオブジェクトに対して色々なメソッドを使うことで値を変更することができます。
add/subメソッド
add/subメソッド
はインスタンス化したDateTimeオブジェクトに対して日付/時刻の加算/減算を行うメソッドです。
$obj = new DateTime('2021/8/29 3:20:30');
$obj->add(new DateInterval('P1YT5H')); // 1年と5時間足す
echo $obj->format('Y/m/d H:i:s'); // 結果:2022/08/29 08:20:30
$obj->sub(new DateInterval('P1YT5H')); // 1年と5時間引く
echo $obj->format('Y/m/d H:i:s'); // 結果:2021/08/29 03:20:30
DateTimeオブジェクトに対してDateIntervalクラスで加算/減算する値を表します。
日付を操作する時はformat文字の前に「P」を、時刻を操作する時はformat文字の前に「T」を記述するのがルールです。
DateIntervalクラスで指定できるformat文字は以下の通りです。
format文字 | 意味 |
---|---|
Y | 年 |
M | 月 |
D | 日 |
H | 時間 |
M | 分 |
S | 秒 |
2日と30分なら「P2DT30M」、1年3ヶ月と3時間なら「P1Y3MT3H」となります。DateTimeオブジェクトに関するformat文字は色々と種類があるので混乱しないようにしましょう。
modifyメソッド
modifyメソッド
はもっと直感的に日付や時刻を変更することができます。
$obj = new DateTime('2000/1/1 00:00:00');
$obj->modify('+2 month');
$obj->modify('+5 day');
$obj->modify('-10 hour');
$obj->modify('+49 second');
echo $obj->format('Y/m/d H:i:s');
// 結果:2000/03/05 14:00:49
引数に正の数か負の数を指定して、変更したい日付/時刻を英語で指定すれば変更することができます。format文字を覚えなくても良いので楽に日付/時刻の操作を行うことができます。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。