データベースのdatetime型カラムの日時をJavaScriptでフォーマットして出力しようとしたら、Chromeでは正常に表示されるのにFirefoxでは表示されないという状態に陥った。
調べたところ、なんと、JavaScriptのDateオブジェクトはブラウザ毎に取り扱えるフォーマットが異なることを知りました。いやぁ、こんなところにも面倒なクロスブラウザの壁があったとは…。
──ということで、この際、徹底的に調べてみようと思い、下記のようなスクリプトを組んでみた。
var datetimes = {
'YYYY-MM-DD HH:mm:ss': '2015-09-08 10:26:31',
'YYYY-MM-DDTHH:mm:ss': '2015-09-08T10:26:31',
'YYYY-MM-DDTHH:mm:ssZ': '2015-09-08T10:26:31Z',
'YYYY-MM-DDTHH:mm:ss.sssZ': '2015-09-08T10:26:31.000Z',
'YYYY-MM-DDTHH:mm:ss+hh:mm': '2015-09-08T10:26:31+09:00',
'YYYY/MM/DD HH:mm:ss': '2015/09/08 10:26:31',
'YYYY/MM/DDTHH:mm:ss': '2015/09/08T10:26:31',
'YYYY/MM/DDTHH:mm:ssZ': '2015/09/08T10:26:31Z',
'YYYY/MM/DDTHH:mm:ss.sssZ': '2015/09/08T10:26:31.000Z',
'YYYY/MM/DDTHH:mm:ss+hh:mm': '2015/09/08T10:26:31+09:00'
};
var html = '<ol>';
for (var k in datetimes) {
console.info({ k: new Date(datetimes[k]) });
html += '<li><label>'+k+'</label>: '+new Date(datetimes[k])+'</li>';
}
html += '</ol>';
document.write(html);
そして、各ブラウザでの出力結果は、
| date format | Chrome(45.x) | firefox(40.x) | Safari(5.1.7) | Opera(31.0) | IE11 |
|---|---|---|---|---|---|
| YYYY-MM-DD HH:mm:ss | Tue Sep 08 2015 10:26:31 GMT+0900 (東京 (標準時)) | Invalid Date | Invalid Date | Tue Sep 08 2015 10:26:31 GMT+0900 (東京 (標準時)) | Invalid Date |
| YYYY-MM-DDTHH:mm:ss | Tue Sep 08 2015 19:26:31 GMT+0900 (東京 (標準時)) | Tue Sep 08 2015 10:26:31 GMT+0900 | Invalid Date | Tue Sep 08 2015 19:26:31 GMT+0900 (東京 (標準時)) | Tue Sep 08 2015 10:26:31 GMT+0900 (東京 (標準時)) |
| YYYY-MM-DDTHH:mm:ssZ | Tue Sep 08 2015 19:26:31 GMT+0900 (東京 (標準時)) | Tue Sep 08 2015 19:26:31 GMT+0900 | Tue Sep 08 2015 19:26:31 GMT+0900 ( (W)) | Tue Sep 08 2015 19:26:31 GMT+0900 (東京 (標準時)) | Tue Sep 08 2015 19:26:31 GMT+0900 (東京 (標準時)) |
| YYYY-MM-DDTHH:mm:ss.sssZ | Tue Sep 08 2015 19:26:31 GMT+0900 (東京 (標準時)) | Tue Sep 08 2015 19:26:31 GMT+0900 | Tue Sep 08 2015 19:26:31 GMT+0900 ( (W)) | Tue Sep 08 2015 19:26:31 GMT+0900 (東京 (標準時)) | Tue Sep 08 2015 19:26:31 GMT+0900 (東京 (標準時)) |
| YYYY-MM-DDTHH:mm:ss+hh:mm | Tue Sep 08 2015 10:26:31 GMT+0900 (東京 (標準時)) | Tue Sep 08 2015 10:26:31 GMT+0900 | Tue Sep 08 2015 10:26:31 GMT+0900 ( (W)) | Tue Sep 08 2015 10:26:31 GMT+0900 (東京 (標準時)) | Tue Sep 08 2015 10:26:31 GMT+0900 (東京 (標準時)) |
| YYYY/MM/DD HH:mm:ss | Tue Sep 08 2015 10:26:31 GMT+0900 (東京 (標準時)) | Tue Sep 08 2015 10:26:31 GMT+0900 | Tue Sep 08 2015 10:26:31 GMT+0900 ( (W)) | Tue Sep 08 2015 10:26:31 GMT+0900 (東京 (標準時)) | Tue Sep 08 2015 10:26:31 GMT+0900 (東京 (標準時)) |
| YYYY/MM/DDTHH:mm:ss | Invalid Date | Invalid Date | Invalid Date | Invalid Date | Tue Sep 08 2015 12:26:31 GMT+0900 (東京 (標準時)) |
| YYYY/MM/DDTHH:mm:ssZ | Invalid Date | Invalid Date | Invalid Date | Invalid Date | Invalid Date |
| YYYY/MM/DDTHH:mm:ss.sssZ | Invalid Date | Invalid Date | Invalid Date | Invalid Date | Invalid Date |
| YYYY/MM/DDTHH:mm:ss+hh:mm | Invalid Date | Invalid Date | Invalid Date | Invalid Date | Invalid Date |
──となった。
う~む、すべてのモダンブラウザで利用できる日時フォーマットはYYYY-MM-DDTHH:mm:ssZとYYYY-MM-DDTHH:mm:ss.sssZ、YYYY-MM-DDTHH:mm:ss+hh:mm、YYYY/MM/DD HH:mm:ssの4つしかない。
そのうち、タイムゾーンのローカル時間で返してくれるのは、YYYY-MM-DDTHH:mm:ss+hh:mmとYYYY/MM/DD HH:mm:ssの2つとなる。
まぁ、汎用的な処理を考えた場合、タイムゾーン補正値の指定は何気に面倒なので、使い勝手が良いのはYYYY/MM/DD HH:mm:ssの一択になる(可用性が低いなぁ…)。
ちなみに、MySQLなどのdatetime型カラムの値は‘YYYY-MM-DD HH:mm:ss`なので、この値をベースにしてJavaScriptでDateオブジェクトを生成する場合、
var datetime = new Date(datetime_from_db.replace(/\-/g, '/'));
──と云うように-を/に変換してあげれば良い。