PHPでRFC3339形式のタイムスタンプを表示する

(1/1)
インターネットのコンテンツは、世界中で閲覧することができる。
コンテンツの中にある時刻表記は、クライアント PC が置かれている地域の現地時間なのか、それともサーバが置かれている地域の現地時間なのか、はたまた世界標準時なのか――タイムゾーンを明らかにする必要がある。
そこで今回は、与えた日時をインターネットの標準形式であるRFC 3339 形式で表示するプログラムを紹介する。

サンプル・プログラム

サンプル・プログラムの解説:UNIX時間をUTCに変換

ユーザー関数 unix2utc は、与えた UNIX 時間を RFC 3339 形式の UTC(協定世界時)に変換する。
UNIX タイムスタンプは、UNIX epoch(1970 年 1 月 1 日 0 時 0 分 0秒)を 0 とする秒数である。これをUTCに変換するには、組み込み関数  gmdate  を使う。

RFC3339形式の UTC表示は、「年:月:日 T 時:分:秒Z」である。年は西暦、時は 24 時制である。月、日、時、分、秒が 1 桁であるときには 2 桁目を 0 で埋める(ゼロサプレス)。

0016: /**
0017:  * UNIXタイムスタンプからRFC3339 UTC タイムスタンプを返す
0018:  * @param int $unix UNIXタイムスタンプ,Unix epoch(1970年1月1日 00:00:00 GMT))からの通算秒
0019:  * @return RFC3339 UTC
0020: */
0021: function unix2utc($unix) {
0022:     return (gmdate("Y-m-d", $unix) . "T" . gmdate("H:i:s", $unix) . "Z");
0023: }

サンプル・プログラムの解説:UTCをローカル時間に変換

ユーザー関数 utc2local は、与えた RFC 3339 形式UTCRFC3339 形式ローカル時間(現地時間)に変換する。
1番目の引き数として RFC3339 形式UTC、2番目の引数としてローカル時間と UTC との差(時)、3番目の引数としてローカル時間と UTC の差(分)を指定する。
関数  func_get_arg  により可変引数に対応しており、3番目の引数は省略可能である。

RFC3339のローカル時間表記は、「年:月:日 T 時:分:秒±UTC との差(時):UTC との差(分)」である。規格上、UTC の時、分、秒は省略可能であるので、省略された場合の処理が回りくどくなっている。
UTCは、いったん UNIX タイムスタンプに戻し、あらためてローカル時間表記に変換する。

0025: /**
0026:  * RFC3339 UTC タイムスタンプをローカルのタイムスタンプに変換する
0027:  * @param string $utc RFC3339 UTCタイムスタンプ
0028:  * @param int tz_hour UTCと地方時の差(時間)
0029:  * @param int tz_min UTCと地方時の差(分)(省略可能)
0030:  * @return string ローカルのタイムスタンプ(RF3339表記)
0031:  *                 NULL=エラー(入力文字列が規定外など)
0032: */
0033: function utc2local($utc$tz_hour) {
0034:     $tz_hour = func_get_arg(1);
0035:     //可変長変数を使う
0036:     $tz_min = (@func_num_args() >= 3) ? func_get_arg(2) : (0);
0037: 
0038:     if (preg_match("/[0-9]+-[0-9]+-[0-9]+T[0-9]+:[0-9]+:[0-9]+Z/", $utc) == 1) {
0039:         list($year$month$day$hour$minuite$second) = sscanf($utc, "%d-%d-%dT%d:%d:%dZ");
0040:     } else if (preg_match("/[0-9]+-[0-9]+-[0-9]+T[0-9]+:[0-9]+Z/", $utc) == 1) {
0041:         list($year$month$day$hour$minuite) = sscanf($utc, "%d-%d-%dT%d:%dZ");
0042:         $second = 0;
0043:     } else if (preg_match("/[0-9]+-[0-9]+-[0-9]+T[0-9]+Z/", $utc) == 1) {
0044:         list($year$month$day$hour$minuite) = sscanf($utc, "%d-%d-%dT%dZ");
0045:         $minuite = 0;    $second = 0;
0046:     } else if (preg_match("/[0-9]+-[0-9]+-[0-9]+Z/", $utc) == 1) {
0047:         list($year$month$day$hour$minuite) = sscanf($utc, "%d-%d-%dZ");
0048:         $hour = 0;   $minuite = 0;    $second = 0;
0049:     } else {
0050:         return NULL; //UTC書式エラー
0051:     }
0052: 
0053:     $tt = mktime($hour + $tz_hour$minuite + $tz_min$second$month$day$year);
0054: 
0055:     $s = date("Y-m-d", $tt) . "T" . date("H:i:s", $tt);
0056:     $f = ($tz_hour < 0) ? "-" : "+";
0057: 
0058:     return sprintf("%s%s%02d:%02d", $s$fabs($tz_hour), $tz_min);
0059: }

サンプル・プログラムの解説:メインプログラム

メインプログラムでは、組み込み関数  time  により内蔵時計の時間を取得し、これをUTCに変換する。そして、日本標準時(JST)に変換する。JST は UTC + 9 時間である。

なお、time の代わりに組み込み関数  filemtime  を使えば、ファイルのタイムスタンプ(最終更新日時)を RFC3339 形式にすることができる。

余談になるが、標準関数 [mktime:time] の引き数の順番は、時,分,秒,月,日,年だが、年の部分は2桁または4桁の西暦年号を代入する。2桁の場合、 0~69 の間の値は 2000~2069 に、70~100 は 1970~2000 にマッピングされる。

0061: // メインプログラム ============================================================
0062:     $utc = unix2utc(time());         //内蔵時計の日時をUTCに変換する
0063:     $local = utc2local($utc, 9);     //JST = UTC + 09:00
0064: 
0065: // 表示処理 =================================================================
0066: echo <<< EOF
0067: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
0068:  "http://www.w3.org/TR/html4/loose.dtd">
0069: <html lang="ja">
0070: <head>
0071: <meta http-equiv="Content-Type" content="text/html; charset={$EncodeOutput}" />
0072: <title>現在時刻(RFC3339)</title>
0073: <meta name="author" content="studio pahoo" />
0074: <meta name="copyright" content="studio pahoo" />
0075: <meta name="ROBOTS" content="NOINDEX,NOFOLLOW" />
0076: </head>
0077: <body>
0078: <h1>■現在時刻(RFC3339)</h1>
0079: <table border="1" cellpadding="5">
0080: <tr>
0081: <td>UTC</td>
0082: <td>{$utc}</td>
0083: </tr>
0084: <tr>
0085: <td>JST</td>
0086: <td>$local</td>
0087: </tr>
0088: </table>
0089: </html>
0090: 
0091: EOF;

参考サイト

(この項おわり)
header