PHPの日付書式とJavaScriptの連携

2018-12-13 16:55:12

PHPのDateの書式に関する部分である

実際に使う場合はDateよりもタイムゾーンが個別に設定できるDateTimeの使用を推奨する

混沌の書式

2018-12-13 16:56:12

日時を表すフォーマットは多種多様に有り、様々なシステムにおいてもその書式は混沌の世界と化している。特定の規格を採用しようと思っても、その中での表現方法に幅があったり拡張規格が存在したりと、耐えがたき苦痛が拷問のように押し寄せてくる。こうしている間にも新たなフォーマットが生み出され、プログラマを苦しめる魔物となり、そも魔物は着々と力をためていることだろう。

 眼前に表示されている日付はUTCなのかローカルタイムなのか、これから入力すべきデータはどっちに合わせてどの形式にすればいいのか、データの幅はグレゴリオ暦で持てるのかUnixTimeなのか、もはやいい加減にしてくれと言う状況である。

 さらに恐ろしいのは、各言語のランタイムライブラリ、DBやブラウザの種類、そういった様々な違いによって解釈できたり出来なかったりする。気分は洗濯機の中に放り込まれたぬいぐるみの気分だ。このままでは縫い付けられた目玉の一つも落としてしまうことだろう。

 ということで今回はPHPとJavaScriptに絞って、データのやりとりを確認していきたい。

PHPの定数として用意されている書式

2018-12-13 16:56:45

 PHPは日付を自由に扱うことが出来る。入出力に使う書式はユーザ側が設定できるのだ。だが物臭な人のために、わざわざ定義済みの書式を用意してくれている。ではこれを使って、PHPから吐き出した日時のデータが、JavaScriptできちんと読み込まれるのか検証していこう。

用意するプログラム

2018-12-13 16:57:02

 PHPのDateTimeで定義されている定数のうち、フォーマットが重複するものは弾いている


<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8"/> 
    <title>日付変換の確認</title>
    <script type='text/javascript'>
        addEventListener("DOMContentLoaded",function(){
            var body = document.body;
            var dates = <?php getDateValues()?> //PHPから日付を受け取る
            var table = document.createElement('table')
            table.border=1
            var r = table.insertRow()
            r.innerHTML = "<TH>名前</TH><TH>フォーマット</TH><TH>PHPの出力</TH><TH>JavaScriptの認識</TH>"
            for(var i=0,length=dates.length;i<length;i++){
                r = table.insertRow()
                var d = dates[i]
                r.insertCell().textContent = d.name
                r.insertCell().textContent = d.format
                r.insertCell().textContent = d.value
                r.insertCell().textContent = new Date(d.value) //JavaScriptで変換を試みる
            }
            document.body.appendChild(table)
        })
    </script>
</head>
<body>
</body>
</html>
<?php
//PHPから各種フォーマットを出力する
function getDateValues(){
    $formats = [
        'ATOM'=>DateTime::ATOM,
        'COOKIE'=>DateTime::COOKIE,
        'ISO8601'=>DateTime::ISO8601,
        'RFC822'=>DateTime::RFC822,
        'RFC850'=>DateTime::RFC850,
        'RFC3339'=>DateTime::RFC3339,
        'RSS'=>DateTime::RSS,
        'W3C'=>DateTime::W3C
    ];
    $date = new DateTime();
    $date->setTimeZone( new DateTimeZone('UTC'));
    foreach($formats as $key => $format){
        $result[] = [
            'name'=>$key,
            'format'=>$format,
            'value'=>$date->format($format)
        ];
    }
    echo json_encode($result);
}


 PHPの吐き出す日時データをJavaScriptに喰わせるプログラムなのだが、ふと気がつくと変にアクロバティックなプログラムになってしまった

各種ブラウザごとの結果

2018-12-13 16:58:29

IE11

2018-12-13 16:58:55

名前フォーマットPHPの出力JavaScriptの認識
ATOMY-m-d\TH:i:sP2018-12-13T07:59:57+00:00Thu Dec 13 2018 16:59:57 GMT+0900 (東京 (標準時))
COOKIEl, d-M-Y H:i:s TThursday, 13-Dec-2018 07:59:57 UTCInvalid Date
ISO8601Y-m-d\TH:i:sO2018-12-13T07:59:57+0000Invalid Date
RFC822D, d M y H:i:s OThu, 13 Dec 18 07:59:57 +0000Invalid Date
RFC850l, d-M-y H:i:s TThursday, 13-Dec-18 07:59:57 UTCInvalid Date
RFC2822D, d M Y H:i:s OThu, 13 Dec 2018 07:59:57 +0000Thu Dec 13 2018 16:59:57 GMT+0900 (東京 (標準時))
RFC3339Y-m-d\TH:i:sP2018-12-13T07:59:57+00:00Thu Dec 13 2018 16:59:57 GMT+0900 (東京 (標準時))
RSSD, d M Y H:i:s OThu, 13 Dec 2018 07:59:57 +0000Thu Dec 13 2018 16:59:57 GMT+0900 (東京 (標準時))
W3CY-m-d\TH:i:sP2018-12-13T07:59:57+00:00Thu Dec 13 2018 16:59:57 GMT+0900 (東京 (標準時))

Edge

2018-12-13 16:59:11

名前フォーマットPHPの出力JavaScriptの認識
ATOMY-m-d\TH:i:sP2018-12-13T08:02:16+00:00Thu Dec 13 2018 17:02:16 GMT+0900 (東京 (標準時))
COOKIEl, d-M-Y H:i:s TThursday, 13-Dec-2018 08:02:16 UTCInvalid Date
ISO8601Y-m-d\TH:i:sO2018-12-13T08:02:16+0000Thu Dec 13 2018 17:02:16 GMT+0900 (東京 (標準時))
RFC822D, d M y H:i:s OThu, 13 Dec 18 08:02:16 +0000Invalid Date
RFC850l, d-M-y H:i:s TThursday, 13-Dec-18 08:02:16 UTCInvalid Date
RFC2822D, d M Y H:i:s OThu, 13 Dec 2018 08:02:16 +0000Thu Dec 13 2018 17:02:16 GMT+0900 (東京 (標準時))
RFC3339Y-m-d\TH:i:sP2018-12-13T08:02:16+00:00Thu Dec 13 2018 17:02:16 GMT+0900 (東京 (標準時))
RSSD, d M Y H:i:s OThu, 13 Dec 2018 08:02:16 +0000Thu Dec 13 2018 17:02:16 GMT+0900 (東京 (標準時))
W3CY-m-d\TH:i:sP2018-12-13T08:02:16+00:00Thu Dec 13 2018 17:02:16 GMT+0900 (東京 (標準時))

Firefox

2018-12-13 16:59:17

名前フォーマットPHPの出力JavaScriptの認識
ATOMY-m-d\TH:i:sP2018-12-13T08:21:09+00:00Thu Dec 13 2018 17:21:09 GMT+0900 (日本標準時)
COOKIEl, d-M-Y H:i:s TThursday, 13-Dec-2018 08:21:09 UTCMon Dec 13 -2018 17:40:08 GMT+0918 (日本標準時)
ISO8601Y-m-d\TH:i:sO2018-12-13T08:21:09+0000Thu Dec 13 2018 17:21:09 GMT+0900 (日本標準時)
RFC822D, d M y H:i:s OThu, 13 Dec 18 08:21:09 +0000Thu Dec 13 2018 17:21:09 GMT+0900 (日本標準時)
RFC850l, d-M-y H:i:s TThursday, 13-Dec-18 08:21:09 UTCInvalid Date
RFC2822D, d M Y H:i:s OThu, 13 Dec 2018 08:21:09 +0000Thu Dec 13 2018 17:21:09 GMT+0900 (日本標準時)
RFC3339Y-m-d\TH:i:sP2018-12-13T08:21:09+00:00Thu Dec 13 2018 17:21:09 GMT+0900 (日本標準時)
RSSD, d M Y H:i:s OThu, 13 Dec 2018 08:21:09 +0000Thu Dec 13 2018 17:21:09 GMT+0900 (日本標準時)
W3CY-m-d\TH:i:sP2018-12-13T08:21:09+00:00Thu Dec 13 2018 17:21:09 GMT+0900 (日本標準時)

Chrome

2018-12-13 16:59:21

名前フォーマットPHPの出力JavaScriptの認識
ATOMY-m-d\TH:i:sP2018-12-13T07:59:43+00:00Thu Dec 13 2018 16:59:43 GMT+0900 (日本標準時)
COOKIEl, d-M-Y H:i:s TThursday, 13-Dec-2018 07:59:43 UTCThu Dec 13 2018 16:59:43 GMT+0900 (日本標準時)
ISO8601Y-m-d\TH:i:sO2018-12-13T07:59:43+0000Thu Dec 13 2018 16:59:43 GMT+0900 (日本標準時)
RFC822D, d M y H:i:s OThu, 13 Dec 18 07:59:43 +0000Thu Dec 13 2018 16:59:43 GMT+0900 (日本標準時)
RFC850l, d-M-y H:i:s TThursday, 13-Dec-18 07:59:43 UTCThu Dec 13 2018 16:59:43 GMT+0900 (日本標準時)
RFC2822D, d M Y H:i:s OThu, 13 Dec 2018 07:59:43 +0000Thu Dec 13 2018 16:59:43 GMT+0900 (日本標準時)
RFC3339Y-m-d\TH:i:sP2018-12-13T07:59:43+00:00Thu Dec 13 2018 16:59:43 GMT+0900 (日本標準時)
RSSD, d M Y H:i:s OThu, 13 Dec 2018 07:59:43 +0000Thu Dec 13 2018 16:59:43 GMT+0900 (日本標準時)
W3CY-m-d\TH:i:sP2018-12-13T07:59:43+00:00Thu Dec 13 2018 16:59:43 GMT+0900 (日本標準時)

まとめ

2018-12-13 17:22:41

とりあえずIE11で確認しておけば、大抵のものには対応できる

こういう時にこそ、進化しないブラウザの真価が発揮されるのだ