混沌の書式
日時を表すフォーマットは多種多様に有り、様々なシステムにおいてもその書式は混沌の世界と化している。特定の規格を採用しようと思っても、その中での表現方法に幅があったり拡張規格が存在したりと、耐えがたき苦痛が拷問のように押し寄せてくる。こうしている間にも新たなフォーマットが生み出され、プログラマを苦しめる魔物となり、そも魔物は着々と力をためていることだろう。
眼前に表示されている日付はUTCなのかローカルタイムなのか、これから入力すべきデータはどっちに合わせてどの形式にすればいいのか、データの幅はグレゴリオ暦で持てるのかUnixTimeなのか、もはやいい加減にしてくれと言う状況である。
さらに恐ろしいのは、各言語のランタイムライブラリ、DBやブラウザの種類、そういった様々な違いによって解釈できたり出来なかったりする。気分は洗濯機の中に放り込まれたぬいぐるみの気分だ。このままでは縫い付けられた目玉の一つも落としてしまうことだろう。
ということで今回はPHPとJavaScriptに絞って、データのやりとりを確認していきたい。
PHPの定数として用意されている書式
PHPは日付を自由に扱うことが出来る。入出力に使う書式はユーザ側が設定できるのだ。だが物臭な人のために、わざわざ定義済みの書式を用意してくれている。ではこれを使って、PHPから吐き出した日時のデータが、JavaScriptできちんと読み込まれるのか検証していこう。
用意するプログラム
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時点で最新版
##IE11
名前 | フォーマット | PHPの出力 | JavaScriptの認識 |
---|---|---|---|
ATOM | Y-m-d\TH:i:sP | 2018-12-13T06:44:44+00:00 | Thu Dec 13 2018 15:44:44 GMT+0900 (東京 (標準時)) |
COOKIE | l, d-M-Y H:i:s T | Thursday, 13-Dec-2018 06:44:44 UTC | Invalid Date |
ISO8601 | Y-m-d\TH:i:sO | 2018-12-13T06:44:44+0000 | Invalid Date |
RFC822 | D, d M y H:i:s O | Thu, 13 Dec 18 06:44:44 +0000 | Invalid Date |
RFC850 | l, d-M-y H:i:s T | Thursday, 13-Dec-18 06:44:44 UTC | Invalid Date |
RFC3339 | Y-m-d\TH:i:sP | 2018-12-13T06:44:44+00:00 | Thu Dec 13 2018 15:44:44 GMT+0900 (東京 (標準時)) |
RSS | D, d M Y H:i:s O | Thu, 13 Dec 2018 06:44:44 +0000 | Thu Dec 13 2018 15:44:44 GMT+0900 (東京 (標準時)) |
W3C | Y-m-d\TH:i:sP | 2018-12-13T06:44:44+00:00 | Thu Dec 13 2018 15:44:44 GMT+0900 (東京 (標準時)) |
最も認識できないのは、最古のブラウザたる所以である
ちなみにISO8601は「2018-12-13T06:44:44Z」のようにすると認識してくれる
##Edge
名前 | フォーマット | PHPの出力 | JavaScriptの認識 |
---|---|---|---|
ATOM | Y-m-d\TH:i:sP | 2018-12-13T06:50:53+00:00 | Thu Dec 13 2018 15:50:53 GMT+0900 (東京 (標準時)) |
COOKIE | l, d-M-Y H:i:s T | Thursday, 13-Dec-2018 06:50:53 UTC | Invalid Date |
ISO8601 | Y-m-d\TH:i:sO | 2018-12-13T06:50:53+0000 | Thu Dec 13 2018 15:50:53 GMT+0900 (東京 (標準時)) |
RFC822 | D, d M y H:i:s O | Thu, 13 Dec 18 06:50:53 +0000 | Invalid Date |
RFC850 | l, d-M-y H:i:s T | Thursday, 13-Dec-18 06:50:53 UTC | Invalid Date |
RFC3339 | Y-m-d\TH:i:sP | 2018-12-13T06:50:53+00:00 | Thu Dec 13 2018 15:50:53 GMT+0900 (東京 (標準時)) |
RSS | D, d M Y H:i:s O | Thu, 13 Dec 2018 06:50:53 +0000 | Thu Dec 13 2018 15:50:53 GMT+0900 (東京 (標準時)) |
W3C | Y-m-d\TH:i:sP | 2018-12-13T06:50:53+00:00 | Thu Dec 13 2018 15:50:53 GMT+0900 (東京 (標準時)) |
IEよりもISO8601の対応が良くなったが、毛が生えた程度で終わっている
##Firefox
名前 | フォーマット | PHPの出力 | JavaScriptの認識 |
---|---|---|---|
ATOM | Y-m-d\TH:i:sP | 2018-12-13T06:50:01+00:00 | Thu Dec 13 2018 15:50:01 GMT+0900 |
COOKIE | l, d-M-Y H:i:s T | Thursday, 13-Dec-2018 06:50:01 UTC | Invalid Date |
ISO8601 | Y-m-d\TH:i:sO | 2018-12-13T06:50:01+0000 | Thu Dec 13 2018 15:50:01 GMT+0900 |
RFC822 | D, d M y H:i:s O | Thu, 13 Dec 18 06:50:01 +0000 | Thu Dec 13 2018 15:50:01 GMT+0900 |
RFC850 | l, d-M-y H:i:s T | Thursday, 13-Dec-18 06:50:01 UTC | Invalid Date |
RFC3339 | Y-m-d\TH:i:sP | 2018-12-13T06:50:01+00:00 | Thu Dec 13 2018 15:50:01 GMT+0900 |
RSS | D, d M Y H:i:s O | Thu, 13 Dec 2018 06:50:01 +0000 | Thu Dec 13 2018 15:50:01 GMT+0900 |
W3C | Y-m-d\TH:i:sP | 2018-12-13T06:50:01+00:00 | Thu Dec 13 2018 15:50:01 GMT+0900 |
ちょっと強くなったが、気を抜くとやられる
##Chrome
名前 | フォーマット | PHPの出力 | JavaScriptの認識 |
---|---|---|---|
ATOM | Y-m-d\TH:i:sP | 2018-12-13T06:51:15+00:00 | Thu Dec 13 2018 15:51:15 GMT+0900 (日本標準時) |
COOKIE | l, d-M-Y H:i:s T | Thursday, 13-Dec-2018 06:51:15 UTC | Thu Dec 13 2018 15:51:15 GMT+0900 (日本標準時) |
ISO8601 | Y-m-d\TH:i:sO | 2018-12-13T06:51:15+0000 | Thu Dec 13 2018 15:51:15 GMT+0900 (日本標準時) |
RFC822 | D, d M y H:i:s O | Thu, 13 Dec 18 06:51:15 +0000 | Thu Dec 13 2018 15:51:15 GMT+0900 (日本標準時) |
RFC850 | l, d-M-y H:i:s T | Thursday, 13-Dec-18 06:51:15 UTC | Thu Dec 13 2018 15:51:15 GMT+0900 (日本標準時) |
RFC3339 | Y-m-d\TH:i:sP | 2018-12-13T06:51:15+00:00 | Thu Dec 13 2018 15:51:15 GMT+0900 (日本標準時) |
RSS | D, d M Y H:i:s O | Thu, 13 Dec 2018 06:51:15 +0000 | Thu Dec 13 2018 15:51:15 GMT+0900 (日本標準時) |
W3C | Y-m-d\TH:i:sP | 2018-12-13T06:51:15+00:00 | Thu Dec 13 2018 15:51:15 GMT+0900 (日本標準時) |
なんとパーフェクトである
あらゆる種類をパース可能になっているが、つまりこのブラウザで開発を行うとテストにならないということでもある
まとめ
来年、スギ、ヒノキ、イネの花粉コンボの時期になると、別の問題である元号の切り替えの季節がやって来る。優秀な御方々なら来年の対応などとっくに済ませており、年末は粛々と年の疲れを癒やしていること疑問を挟む余地はない。また、システムに問題など発生するはずもないからGWの10連休を満喫しているはずだ。
それどころかリア充すぎてクリスマスイブの仕込の方が忙しく、そっちの方で気が重くなっているかもしれない。「イブに予定?あ、俺のシステムがUTCになってってマッチングに失敗しちゃってさぁ。予定が入っていないのはミスだよミス」なんて人もいるのかもしれない。全てはシステムに入れた設定が悪いのである