PHPにはいろいろな日時処理の関数があります。ただし、良く使うのは限られているので、その中から基本的な日時処理をとりあえずまとめました。
現在日時を求める
-
Unixタイムスタンプを求める
現在日時のUnix タイムスタンプ (1970 年 1 月 1 日 00:00:00 UTC からの経過秒数) を求めるには、 time()やstrtotime()を使用する方法があります。
$now1 = time(); # 現在が'2014-10-12 21:47:56'の場合、$now1 => 1413118076(整数値) $now2 = strtotime('now') # $now1と同じ値になります。
文字列を求める
現在日時を文字列で表示しますが、その書式を指定する場合、date()かstrftime()を使います。
$s1 = date('Y-m-d H:i:s') # $s1 => '2014-10-12 12:34:56' $s2 = strftime('%Y-%m-%d %H:%M:%S') # $s2は$s1と同じ値になります。
ある関数内で現在日時を異なる形式で必要なケースがあります。 その場合、現在のUnixタイムスタンプを一旦変数に入れ、その値の表示形式を変えて対処します。
$now = time(); $s1 = date('Y-m-d H:i', $now); # $s1 => '2014-10-12 12:34' $s2 = date('Y-m-d H:i:s', $now); # $s2 => '2014-10-12 12:34:56'
ローケルにもとづいた文字列
現在日時を、現在のローケルにもとづいた文字列にする場合は、strftime()を使用します。
現在のローケルにもとづく日時
現在のローケルにもとづく日時の文字列が必要な場合は、"%c"を指定します。
$s1 = strftime('%c') # $s1 => 'Sun Oct 12 12:36:03 2014'
現在のローケルにもとづく日付
現在のローケルにもとづく日付だけの文字列が必要な場合は、"%x"を指定します。
$s2 = strftime('%x') # $s2 => '10/12/14'
現在のローケルにもとづく時刻
現在のローケルにもとづく時刻だけの文字列が必要な場合は、"%X"を指定します。
$s3 = strftime('%X') # $s2 => '12:36:03'
指定した日時を求める
-
Unixタイムスタンプを求める
日時が指定できる場合は、strtotime()や、mktime()などを使用します。 ただし、指定する日時文字列に日本語などが含まれてstrtotime()で処理できないような場合は、一旦文字列から日時情報を取り出す処理が必要となります。
$d1 = strtotime('2014-01-23 12:34:56'); # $d1 => '2014-01-23 12:34:56'の場合、1390448096(整数値) $d2 = mktime(12, 34, 56, 1, 23, 2014); # $d1と同じ値になります。
参考 mktime関数の引数は、mktime(時, 分, 秒, 月, 日, 年)になります。
文字列を求める
ある日時の文字列(ユーザーが選択した日付など)を別の書式に変換したりする場合は以下のような方法があります。
strtotime()でUnixタイムスタンプを求めて、date()かstrftime()
strtotime()でUnixタイムスタンプを求めて、date()か、strftime()で求める書式の文字列に変換します。
$d1 = '2014/01/23 12:34'; # ユーザーなどが選択した日時を変数に入れます。 echo date('Y-m-d H:i:s', strtotime($d1); # '2014-01-23 12:34:00'になります。
注意 日付の文字列に日本語が入っている場合など、strtotime()で処理できない場合があります。
$s1 = '2月27日12時34分'; $s2 = date('Y-m-d H:i:s', strtotime($s1)); # strtotime($s1)がFALSEを返すため、$s2 = '1970-01-01 09:00:00' になります。
この場合は、PHP5.3.0以上ならdate_parse_from_format()、それ以外ならstrptime()や正規表現で日時を取り出して、strtotime()かmktime()でUnixタイムスタンプを求めてから文字列にします。
文字列から日時情報を取り出す
日時の文字列にはいろいろな書式が考えられます。よくある"2014-12-23 18:19:20"のような書式ならstrtotime()が使えますが、 "2014年12月23日"のように日本語が入ると処理できません。ここでは書式が特殊な文字列から日時情報を取り出す方法についての一覧です。
-
date_parse_from_format
-
strptime
-
正規表現
対応: PHP 5.3以上
DateTime::createFromFormat() が理解できるフォーマットの文字列を指定した場合、与えられた文字列の日時情報を連想配列で返します。
$ar = date_parse_from_format('n月j日G時i分', '12月7日23時34分');$ar は以下のようになります。
array(12) { ["year"]=> bool(false) #年の指定が無いので、falseになっています。 ["month"]=> int(12) ["day"]=> int(7) ["hour"]=> int(23) ["minute"]=> int(34) ["second"]=> int(0) ["fraction"]=> bool(false) ["warning_count"]=> int(0) ["warnings"]=> array(0) { } ["error_count"]=> int(0) ["errors"]=> array(0) { } ["is_localtime"]=> bool(false) }
エラーがある場合、[errors]にエラーメッセージが入ります。 以下の例では、23時(24時間指定の文字列)になっているのに、書式で "g" (1~12、または01~12)を指定してるため、エラーが発生しています。
$ar = date_parse_from_format('n月j日g時i分', '12月7日23時34分');
$ar は以下のようになります。array(12) { ["year"]=> bool(false) ["month"]=> int(12) ["day"]=> int(7) ["hour"]=> int(23) ["minute"]=> int(34) ["second"]=> int(0) ["fraction"]=> bool(false) ["warning_count"]=> int(0) ["warnings"]=> array(0) { } ["error_count"]=> int(1) ["errors"]=> array(1) { [9]=> string(30) "Hour can not be higher than 12" } ["is_localtime"]=> bool(false) }
※ PHP 5.1.0以上に対応していますが、OSによって挙動が異なることがあるので、PHP 5.3.0以上では date_parse_from_format()を使うことが推奨されています。
$d = '2014年8月12日 09時13分45秒'; $ar = strptime($d, '%Y年%m月%d日 %H時%M分%S秒');実行すると、$arは以下のようになります。年の"tm_year"は1900年からの経過年なので、プラス1900する必要があります。
array(9) { ["tm_sec"]=> int(45) ["tm_min"]=> int(13) ["tm_hour"]=> int(9) ["tm_mday"]=> int(12) ["tm_mon"]=> int(7) ["tm_year"]=> int(114) ["tm_wday"]=> int(2) ["tm_yday"]=> int(223) ["unparsed"]=> string(0) "" }
書式が決まっている場合、書式のチェックと合わせて正規表現を使う方法もあります。また、特殊な書式で正規表現でしか処理できないようなケースもあります。
$input = '2013年1月23日 12時34分56秒'; $mc = null; if (!preg_match('/^(\d{4})年(\d{1,2})月(\d{1,2})日 (\d{1,2})時(\d{1,2})分(\d{1,2})秒$/', $d, $mc)) { throw new Exception("Error invalid format. " .$input); } $s1 = date('Y-m-d H:i:s', mktime($mc[4], $mc[5], $mc[6], $mc[2], $mc[3], $mc[1])); # '2013-1-23 12:34:56'になります。 $s2 = "$mc[1]-$mc[2]-$mc[3] $mc[4]:$mc[5]:$mc[6]"; # $s1と同じになります。
ある日時から別の日時を求める(何日後、何週間前など)
-
strtotime
ある日付文字列の後に、何日後(例 "+3 day")や何週間前(例 "-2 week")の文字列を続けてstrtotime()を使うと、求める日時のUnixタイムスタンプが求められます。
$s1 = date('Y-m-d H:i:s', strtotime('2014-09-29 +14 day')); # $s1 => '2014-10-13 00:00:00'になります。 $s2 = date('Y-m-d H:i:s', strtotime('2014-09-29 +2 week'); # $s1と同じになります。
過去の場合は、マイナスで日数などを指定します。
$s3 = date('Y-m-d H:i:s', strtotime('2014-09-29 -5 week'); # $s3 => '2014-08-25 00:00:00'になります。
時間をプラス何時間、分をマイナスなど、一度に複数指定することもできます。
$s4 = date('Y-m-d H:i:s', strtotime('2014-09-29 18:29:30 -3 hour +5 minute -12 second'); # $s4 => '2014-09-29 15:34:18'になります。※日数などの指定では、複数形(”days”)だけでなく単数形(”day”)でも大丈夫なので、常に単数形で指定した方がシンプルになります。
サポートする日付と時刻の書式(PHPマニュアル)
文字列から日時情報を取り出して加工
ある日時の文字列から別の日時を求めるような場合は、文字列から日時情報を取り出し、 そのデータからmktimeや、strtotime関数で、目的の日時を求めることもできます。
$input = '14/12/27'; $mc = null; if (!preg_match('/^(\d+)\/(\d+)\/(\d+)$s+$/', $input, $mc)) { throw new Exception("Error"); } $s1 = date('Y-m-d', mktime(0, 0, 0, $mc[2], 1, $mc[1] + 2000)); # 2014年に実行した場合は、$s1 => '2014-12-1' になります。