PHP 時間関係の関数
こんにちは。webチームの黒岩です。
今回は、php内における時刻や日付に関係する関数を紹介していきます。
現在の日付や時間の取得
PHP で現在の日付や時間を得るには、date()関数 や DateTimeクラス を利用します。
date() は、指定した「日付や時刻のフォーマット文字列」から日時の文字列を返します。
DateTimeクラスでは様々な日付や時刻を表すことが出来ます。
一つ一つ解説していきます。
でもその前に・・・
タイムゾーンの指定
時刻の基準を日本時間に合わせましょう。設定の仕方は二通りあります。
- php.ini に記述する場合
date.timezone = Asia/Tokyo
- phpスクリプトで直接指定する場合
<?php date_default_timezone_set ('Asia/Tokyo'); ?>
date()
date()関数 は、指定した「日付や時刻のフォーマット文字列」から「日時の文字列」を返します「 日時の文字列 = date('日付/時刻のフォーマット文字列'); 」。
例えば…
echo date('Y');
Y="Y"ear、つまり現在の年が取得できます。(4桁)
他の時間区分などは最後にお伝えします。
更に、オプションでUNIXタイムスタンプを指定すると、指定したタイムスタンプに合わせた日時の文字列を返します。
日時の文字列 = date('日付/時刻のフォーマット文字列', UNIXタイムスタンプ);
タイムスタンプは、strtotime()
関数 や mktime()
関数 で取得できます。タイムスタンプを省略すると現在日時となります。
例えば今現在が2023年の場合・・
echo date('Y', strtotime('+5 year'));//出力 2028
では、先ほどのdate() の「年 月 日 時 分 秒」を表現するフォーマット文字列を使用して、現在の日時を取得してみましょう。
実行日時 2023-01-01 01:01:01
の場合
echo date('Y-m-d')."<br/>\n";//現在日付 2023-01-01
echo date('H:i:s')."<br/>\n";//現在時間 01:01:01
echo date('Y-m-d H:i:s')."<br/>\n";//現在日時 2023-01-01 01:01:01
結果は↓↓↓
2020-01-01
01:01:01
2020-01-01 01:01:01
となります。
DateTimeクラス
DateTimeクラスは様々な日付や時刻を表現できるクラスです。
DateTimeクラスを呼び出しオブジェクト(インスタンス)を作成します。
オブジェクト = new DateTime();
DateTimeクラスを呼び出す際に日付や時刻を指定することも出来ます。
オブジェクト = new DateTime('日付/時刻のフォーマット文字列');
省略した場合は現在の日時になります。
オブジェクトのformat()
メソッドは、指定した日付や時刻のフォーマット文字列から日時の文字列を返します。
日時の文字列 = オブジェクト->format('日付/時刻のフォーマット文字列');
(文字列の例は後程)
成功すると日時の文字列を返し、失敗すると FALSE を返します。format()
メソッドで指定する日時のフォーマット文字列はdate()
関数で指定するフォーマットと同じです。
実行日時 2020-01-01 01:01:01
の場合
//クラスを呼び出してオブジェクトを作成
$objDateTime = new DateTime();
//format()メソッドで現在日時を出力
echo $objDateTime->format('Y-m-d')."<br/>\n";//現在日付 2020-01-01
echo $objDateTime->format('H:i:s')."<br/>\n";//現在時間 01:01:01
echo $objDateTime->format('Y-m-d H:i:s')."<br/>\n";//現在日時 2020-01-01 01:01:01
結果は↓↓↓
2020-01-01
01:01:01
2020-01-01 01:01:01
となります。
今の時間と指定した時間の差を取得
次にタイムスタンプを使って2つ以上の時刻の差分を計算する方法を紹介します。
タイムスタンプは「1970-1-1 00:00:00
」を起点として経過した秒数を整数(int型)にした値です。
よって、1970年以降の日付の計算であれば、2つ以上のタイムスタンプを用意することで「秒」単位で時間の差分を計算することができるのです。
先ずは二つの時間を用意してその差を求めましょう。以下のコードを見てください。
// 1つ目の時刻
$timestamp = strtotime("2023-01-01 12:00:00");
// 2つ目の時刻
$timestamp2 = strtotime("2023-01-10 12:00:00");
// 2つの時刻の差を計算
var_dump($timestamp2 - $timestamp);
結果は↓↓↓
int(777600)
となります。
こちらのコードでは、「2023年1月1日 12時」と、「2023年1月10日 12時」の2つのタイムスタンプを使って時間の差分を計算しています。
var_dump
関数で出力される「777600」は秒数なので、2つの時間の差分は「777600秒」ということになります。
例えば経過した日数を計算したい場合については、次のように計算します。
var_dump(($timestamp2 - $timestamp)/60/60/24);
結果は↓↓↓
int(9)
となります。
上記のコードでは、秒数を「1分 = 60秒」、「1時間 = 60分」、「1日 = 24時間」の数字をそれぞれ割って計算しています。
今回は2つの時刻が「12時00分00秒」のため計算結果が整数となりますが、ほとんどの場合は綺麗に割り切れないことが多く浮動小数点数(float型)となります。
なのでfloor
関数で小数点以下を切り捨てて表示させるなどしましょう。
strtotime()
少し脱線しますが、strtotime()関数について解説します。
英文形式の日付 や 決められた書式の日付/時刻をUNIXタイムスタンプに変換し取得することが出来る関数です。
つまり、例えば・・
echo strtotime('2023-01-01 01:01:01');
この結果は↓↓↓
1672534861
となります。
ちなみに、こんなこともできます。
実行日時 2020-01-01 01:01:01
の場合
echo strtotime('now');//出力 1672534861
第1引数は now
を入れることで今を指定することができます。
本題
いよいよ、今まで学んだことを通して今の時間と指定した時間の差を出力させてみましょう。
今の日時は 2023-01-01 05:10:49
とし、
指定の時間は 2023-01-01 01:01:01
としましょう。
ソースコードは以下になります。
$datetime = date('Y-m-d H:i:s');
$datetime_ = strtotime('2023-01-01 01:01:01');
$datetime_minus = strtotime($datetime) - $datetime_;
echo $datetime_minus;
結果として、
11592588
と出力できれば成功です!
フォーマット文字列表
取得内容 | フォーマット文字 | 例 | 説明 |
---|---|---|---|
年 | Y | 1999 や 2020 | 年 4 桁の数字 |
y | 99 や 19 | 年 2 桁の数字 | |
L | 1 か 0 | 閏年かどうか。1なら閏年。0なら閏年ではない | |
月 | F | January~December | 月 フルスペルの文字 |
m | 01~12 | 月 数字。先頭にゼロをつける | |
M | Jan~Dec | 月 3 文字形式 | |
n | 1~12 | 月 数字。先頭にゼロをつけない | |
t | 28~31 | 月 指定した月の日数 | |
日 | d | 01~31 | 日 2桁の数字(先頭にゼロがつく場合も) |
j | 1~31 | 日 数字。先頭にゼロをつけない | |
曜日 | D | Mon~Sun | 3文字のテキスト形式 |
I | Sunday~Saturday | フルスペル形式 | |
N | 1~7 | 数字 1(月曜) から 7(日曜) | |
w | 0~6 | 数字 0(日曜) から 6(土曜) | |
W | 1 | 数字 月曜日に始まる年単位の週番号 | |
時 | g | 1~12 | 12時間単位。先頭ゼロなし |
G | 0~23 | 24時間単位。先頭ゼロなし | |
h | 01~12 | 12時間単位。先頭ゼロあり | |
H | 00~23 | 24時間単位。先頭ゼロあり | |
a | am pm | 午前/午後。小文字表示 | |
A | AM PM | 午前/午後。大文字表示 | |
分 | i | 00~59 | 先頭ゼロあり |
秒 | s | 00~59 | 先頭ゼロあり |
全日付 | c | 2020-05-15T01:04:54+09:00 | ISO8601 フォーマット日付 |
r | Wed, 15 May 2020 01:04:54 +0900 | RFC2822 フォーマット日付 |