WEBでよく使われる日付の表記方法W3C-DTFをPHPで扱う為の簡単な関数を作る。本来ならばstrtotime()
を使いたい所だが、残念ながらW3C-DTFだとそのままではうまく動かない。
関数の機能としてはparse_http_date()
と同じ物にし、使いやすい用にUNIXタイムスタンプも返すようにする。
// -------------------------------------------------------------------------
// array parse_w3cdtf(string datetime)
// W3C-DTF形式の日時を項目ごとに分解し、UNIXタイムスタンプと共に返します。
// W3C-DTFについてはhttp://www.w3.org/TR/NOTE-datetimeを参照してください。
// -------------------------------------------------------------------------
function parse_w3cdtf($datetime)
{
// Year
if(preg_match("/^(\d{4})$/", $datetime, $val)) {
$year = $val[1];
// Year and month
} elseif(preg_match("/^([0-9]{4})-(0[1-9]|1[0-2])$/", $datetime, $val)) {
$year = $val[1];
$month = $val[2];
// Complete date
} elseif(preg_match("/^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/", $datetime, $val)) {
$year = $val[1];
$month = $val[2];
$day = $val[3];
// Complete date plus hours and minutes
} elseif(preg_match("/^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T([0-5][0-9]):([0-5][0-9])(Z|(\+|-)[0-5][0-9]:[0-5][0-9])$/", $datetime, $val)) {
$year = $val[1];
$month = $val[2];
$day = $val[3];
$hour = $val[4];
$minute = $val[5];
$timezone = $val[6];
// Complete date plus hours, minutes and seconds
} elseif(preg_match("/^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T([0-5][0-9]):([0-5][0-9]):([0-5][0-9])(Z|(\+|-)[0-5][0-9]:[0-5][0-9])$/", $datetime, $val)) {
$year = $val[1];
$month = $val[2];
$day = $val[3];
$hour = $val[4];
$minute = $val[5];
$second = $val[6];
$timezone = $val[7];
// Complete date plus hours, minutes, seconds and a decimal fraction of a second
} elseif(preg_match("/^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T([0-5][0-9]):([0-5][0-9]):([0-5][0-9]).([0-9]+)(Z|(\+|-)[0-5][0-9]:[0-5][0-9])$/", $datetime, $val)) {
$year = $val[1];
$month = $val[2];
$day = $val[3];
$hour = $val[4];
$minute = $val[5];
$second = $val[6];
$fraction = $val[7];
$timezone = $val[8];
// Not W3C-DTF
} else {
return false;
}
// Offset of Timezone for gmmktime()
if($timezone != "Z") {
$offset_sign = substr($timezone, 0, 1);
$offset_hour = substr($timezone, 1, 2);
$offset_minute = substr($timezone, 4, 2);
}
$timestamp = gmmktime($hour - ($offset_sign . $offset_hour), $minute - ($offset_sign . $offset_minute), $second, $month, $day, $year);
$result = array("year" => $year, "month" => $month, "day" => $day,
"hour" => $hour, "minute" => $minute, "second" => $second,
"fraction" => $fraction, "timezone" => $timezone, "timestamp" => $timestamp);
return $result;
}
W3C-DTFでは6通りの形式が決まっているのでそれに合わせて正規表現を制作した。タイムスタンプを制作する際、gmmktime()
は引数にタイムゾーンをとれないので自前でタイムゾーンのオフセット分を計算する必要がある。