SYSTEM238 / NOTES1 / PHP / PHPでの日時の扱い

NOTES1 PROG1
PHPでの日時の扱い
日付文字列をUnixタイムスタンプに変換したり、逆にタイムスタンプを日付文字列にしたり、日付の加減の方法をノート

date関数とstrtotime関数を使えば日付の操作に必要なほとんどのことができます。

日付を扱う方法にはフレームワークが用意しているもの(ZendFrameworkのZend_Dateなど)やPHPにもJavaっぽく日付を扱えるDateTimeクラスなどがありますが、date関数とstrtotime関数の組み合わせの方が直感的でわかりやすいです。

ただ、日付を計算してUnixタイムスタンプを取得する場合は、strtotime関数よりもmktime関数の方が使い勝手がいい場合があります。

日付文字列を単純にUnixタイムスタンプにしたり簡単な加減をする場合はstrtotime関数を、それ以外はmktime関数という感じでしょうか。

date関数

date — ローカルの日付/時刻を書式化する

//$timestampで指定した日付の日付文字列を取得する
string date ( string $format, int $timestamp = time() )
//現在の日付文字列を取得する
string date ( string $format )

Unixタイムスタンプを日付文字列にするのに使用します。formatで指定できるパラメタのうち、よく使うと思われるものを以降で説明しています。詳細はphp.net:dateを参照してください。

パラメータ

format

//年  -------------------------------
L   閏年であるかどうか 1なら閏年。0なら閏年ではない。
Y   4 桁の数字
y   2 桁の数字
//月  -------------------------------
F   'January' 〜 'December'
M   'Jan 〜 Dec'
m   01 〜 12
n   1 〜 12
//日  -------------------------------
d   01 〜 31
j   1 〜 31
z   0 〜 365
//曜日  -----------------------------
D   'Mon' 〜 'Sun'
N   1(月)〜 7(日)(>=PHP 5.1.0)
w   0(日)〜 6(土)
//週  -------------------------------
W   ISO-8601 月曜日に始まる年単位の週番号 (>=PHP 4.1.0)
//時  -------------------------------
a   'am' / 'pm'
A   'AM' / 'PM'
g   12時 1 〜 12
h   12時 01 〜 12
G   24時 0 〜 23
H   24時 00 〜 23
//分  -------------------------------
i   00 〜 59
//秒  -------------------------------
s   00 〜 59
//タイムゾーン  ---------------------
e   タイムゾーン 例:UTC, GMT, Atlantic/Azores(>=PHP 5.1.0)
T   タイムゾーン 例:EST, MDT ...
O   GMTとの時差 例: +0200
P   GMTとの時差 例: +02:00(>=PHP 5.1.3)
Z   タイムゾーンのオフセット秒数 -43200 〜 50400

timestamp

integer型の Unixタイムスタンプ
省略時のデフォルト値はtime()の返り値となる

使用例

<?php
//タイムゾーン
date_default_timezone_set('Asia/Tokyo');

$weekAry = array('日', '月', '火', '水', '木', '金', '土');
$ts = strtotime('2015/08/07');

echo date("Y/m/d", $ts). "({$weekAry[date('w', $ts)]})";
?>

*コピー&ペーストして実行できます。

strtotime関数

strtotime — 日付文字列を Unixタイムスタンプに変換する

//$nowで指定したUnixタイムスタンプを基準に$timeの日付/時刻文字列で指定したUnixタイムスタンプを取得する
int strtotime ( string $time, int $now = time() )
//現在時刻を基準に$timeの日付/時刻文字列で指定したUnixタイムスタンプを取得する
int strtotime ( string $time )

日時を分割して指定しなければいけないmktime関数と比較すると日付文字列をそのまま扱えるstrtotime関数は楽チンです。ただ、日付の計算をする場合は指定方法に若干の癖があるので注意が必要です。

パラメータ

time

//日  -------------------------------
8桁の数字 '20150505'
'/'区切り '2015/05/05' or '2015/5/5'
'-'区切り '2015-05-01' or '2015-5-1' or '2015-05'
//時  -------------------------------
6桁の数字 '191919'
':'区切り '19:19:19'
//日時  -----------------------------
'/:'区切り '2015/05/05 19:19:19'
//相対形式  -------------------------
昨日 '-1 day'   //-24時間
昨日 'yesterday' //前日 00:00:00
明日 '+1 day'   //+24時間
明日 'tomorrow'  //翌日 00:00:00
...etc

詳細はphp.net:サポートする日付と時刻の書式を参照してください。うまく指定すれば「先月の末日」や「来週の月曜日の日付」などの取得ができます。

now

integer型の Unixタイムスタンプ
省略時のデフォルト値はtime()の返り値となる

使用例

<?php
//タイムゾーン
date_default_timezone_set('Asia/Tokyo');

//日
$val["strtotime('now')"]        = strtotime('now');
$val["strtotime('+2 day')"]     = strtotime('+2 day');
$val["strtotime('2 day')"]      = strtotime('2 day');
$val["strtotime('-2 day')"]     = strtotime('-2 day');
$val["strtotime('2015/08/01')"] = strtotime('2015/08/01');
$val["strtotime('2015-08')"]    = strtotime('2015-08'); //省略時は'-'
$val["strtotime('yesterday')"]  = strtotime('yesterday');
$val["strtotime('tomorrow')"]   = strtotime('tomorrow');
$val["strtotime('yesterday 09:00:00')"] = strtotime('yesterday 09:00:00');

//週
$val["strtotime('+3 week')"] = strtotime('+3 week');
$val["strtotime('-3 week')"] = strtotime('-3 week');

//曜日
$val["strtotime('next sunday')"] = strtotime('next sunday');
$val["strtotime('next sun')"]    = strtotime('next sun');
$val["strtotime('last sunday')"] = strtotime('last sunday');
$val["strtotime('+4 sunday')"]   = strtotime('+4 sunday');
$val["strtotime('first sun of 2015-08')"] = strtotime('first sun of 2015-08');
$val["strtotime('last sun of 2015-08')"]  = strtotime('last sun of 2015-08');

//月
$val["strtotime('+2 month')"] = strtotime('+2 month');
$val["strtotime('-2 month')"] = strtotime('-2 month');
$val["strtotime('2015/08/01 +1 month')"] = strtotime('2015/08/01 +1 month');
$val["strtotime('+1 month', strtotime('2015/08/01'))"] = strtotime('+1 month', strtotime('2015/08/01'));
$val["strtotime('2015/08/31 +1 month')<font color=red>*</font>"] = strtotime('2015/08/31 +1 month');
$val["strtotime('2015-08 +1 month')"] = strtotime('2015-08 +1 month');
$val["strtotime('first day of 2015/08/12')"] = strtotime('first day of 2015/08/12');
$val["strtotime('first day of', strtotime('2015/08/12'))"] = strtotime('first day of', strtotime('2015/08/12'));
$val["strtotime('last day of 2015/08/12')"] = strtotime('last day of 2015/08/12');
$val["strtotime('last day of next month')"] = strtotime('last day of next month');
$val["strtotime('last&nbsp;&nbsp;day of next month')...余計なスペースはNG<font color=red>*</font>"] = strtotime('last  day of next month');

//年
$val["strtotime('+1 year')"] = strtotime('+1 year');
$val["strtotime('-1 year')"] = strtotime('-1 year');
$val["strtotime('-1 year 13:23:33')"]   = strtotime('-1 year 13:23:33');
$val["strtotime('2015/01/01 -1 year')"] = strtotime('2015/01/01 -1 year');
$val["strtotime('-1 year', strtotime('2015/01/01'))"] = strtotime('-1 year', strtotime('2015/01/01'));

//時分秒
$val["strtotime('+2 hour')"] = strtotime('+2 hour');
$val["strtotime('+4 min')"]  = strtotime('+4 min');
$val["strtotime('+6 sec')"]  = strtotime('+6 sec');

echo "<table>\n";
foreach ($val as $k=>$v){
    echo "<tr><td>{$k}</td><td>". date('Y/m/d H:i:s', $v). "</td></tr>\n";
}
echo "<tr><td>strtotime('now') - strtotime('today')...今日の 0時からの秒数</td><td>". (strtotime('now') - strtotime('today')). "</td></tr>\n";
echo "<tr><td>strtotime('now') - strtotime('today 10:00:00')...今日の10時からの秒数</td><td>". (strtotime('now') - strtotime('today 10:00:00')). "</td></tr>\n";
echo '</table>';
?>

*コピー&ペーストして実行できます。

mktime関数

mktime — 日付を Unix のタイムスタンプとして取得する

int mktime ( int $hour )
int mktime ( int $hour, int $minute = date("i") )
int mktime ( int $hour, int $minute = date("i"), int $second = date("s") )
int mktime ( int $hour, int $minute = date("i"), int $second = date("s"), int $month = date("n") )
int mktime ( int $hour, int $minute = date("i"), int $second = date("s"), int $month = date("n"), int $day = date("j"))
int mktime ( int $hour, int $minute = date("i"), int $second = date("s"), int $month = date("n"), int $day = date("j"), int $year = date("Y"))

左から時, 分, 秒, 月, 日, 年の並びになっています。

日時を分割して指定する必要があるので若干面倒くさいのですが、計算をする場合はそれぞれの数値を単純に加減するだけなのでstrtotime関数よりわかりやすかったりします。

パラメータ

hour

month、day と year で決まる日付の 0時から数えた「時」。負の値は、その日の 0時から前にさかのぼった時間を表します。 23より大きい値は、その翌日以降の時間を表します。

minute

hour時 0分から数えた「分」。 負の値は、その前の時刻を表します。 59より大きい値は、その次の時間以降の時間を表します。省略時は現在の分です。

second

minute分 0秒から数えた「秒」。 負の値は、その前の時刻を表します。 59より大きい値は、その次の分以降の時間を表します。省略時は現在の秒です。

month

前年末から数えた月数。1 〜 12の場合は、カレンダーどおりのその年の「月」を表します。(負の値を含めた) 1より小さい値は、前年の月を逆順でたどります。 つまり 0なら 12月、-1 なら 11月になります。 12より大きい値は、その翌年以降の月を表します。省略時は現在の月です。

day

前月末から数えた日数。1 〜 28、29、30、31(月によって異なる)までの場合は、その月の「日」を表します。(負の値を含めた) 1より小さい値は、前月の日を逆順でたどります。 つまり 0なら前月の末日、-1ならそのさらに前日になります。 その月の日数より大きい値は、翌月以降の日を表します。省略時は現在の日です。

year

年。4桁の値でしていします。一般的なシステム(time_t が 32 ビットの符号付き整数)では yearとして有効な範囲は 1901 〜 2038です。(ただし、WindowsでPHP 5.1.0より前のバージョンでは 1970 〜 2038 です)省略時は現在の年です。

使用例

//タイムゾーン
date_default_timezone_set('Asia/Tokyo');

$dateStr = '2014/8/31';
list($yyyy, $mm, $dd) = explode('/', $dateStr);

echo "{$dateStr} +1ヶ月 -> ". date('Y/m/d H:i:s', mktime(0, 0, 0, $mm + 1, $dd, $yyyy)). '<font color="red">*</font>'. "<br>\n"; 
echo "{$dateStr} +1ヶ月の初日 -> ". date('Y/m/d H:i:s', mktime(0, 0, 0, $mm + 1, 1, $yyyy)). "<br>\n"; 
echo "{$dateStr} +1ヶ月の末日 -> ". date('Y/m/d H:i:s', mktime(0, 0, 0, $mm + 2, 0, $yyyy)). "<br>\n"; 

*コピー&ペーストして実行できます。