Javascript でニートな日付文字列を書く


ニートっていっても NEET じゃないですよ。neat です。こぎれいとか、さっぱりとか、そんな意味ですね。

そもそもは <ins> タグの datetime 属性を綺麗に見せたい! と思ったのが発端です。この辺 の記事を読みまして設定してみたのですが、日付文字列がそのままだといまいちわかりにくい。

<ins datetime="2012-01-23T12:34:56+09:00">さんぷる!</ins>

さんぷる!

そこで、最近の日付についてはもう少しわかりやすく出来ないか、Javascript でごにょごにょやってみました。こんな風に変わります。

さんぷる!

ソースコード

いつもと気分を変えて、Gist に貼ってみました。

実行例

引数にエポック秒、または適切な日付文字列を与えると分かりやすい文字列で返します。

alert(new NeatTimeString(1349998770000));
// 'just now' と返す。(この記事の投稿時点の話)
alert(new NeatTimeString('2012-10-12T08:39:30+09:00'));
// 同じ結果を返す。
alert(new NeatTimeString('2012/10/12'));
// 'today' と返す。少々適当な書式でも ok
alert(new NeatTimeString('2012/10/10'));
// 数日前なら曜日を返す。この場合は 'Wednesday'
alert(new NeatTimeString('2012/08/01'));
// しばらく前ならそのまま返す。このときなんと返すかはブラウザによる。

IE8 爆発しろ!

突然ですが、いや、毎度のことですが、IE8 にはイライラさせられます。

このスクリプトを書いたそもそもの目的、<ins><del>datetime 属性は W3CDTF 形式 で書くことがお作法になっております。例にも挙げた、2012-10-12T08:39:30+09:00、こんなやつですね。

ところがこれ、IE8 の new Date() コンストラクタの引数として認識されないんですね。Firefox や Chrome や Safari では問題ないのに。

alert(new Date('2012-10-12T08:39:30+09:00')); // => NaN

いろいろ試した結果、以下のように変換すれば IE8 でも問題ないようです。

  • 年・月・日の区切りにはスラッシュ('/')を使う。
  • タイムゾーン表記のコロン(':')を除く。また、'Z''+0000' に置換する。
alert(new Date('2012/10/12T08:39:30+0900')); // => OK!

もちろん、W3CDTF 形式を new Date() コンストラクタが認識するのは Javascript としては仕様外の働きであるはずです。

しかし他のブラウザが軒並み出来ることを、あえて外してくる IE8 にはホント腹が立ちます。しかも、IE9 では W3CDTF 形式が使えるようになっている わけですしね。うむ。IE9。おまえはいいやつだ。

条件付きコメントで IE8 に対応させる

というわけで今回のスクリプトでは、以下の部分で IE8 の対応をしています。この Javascript としては珍妙な構文は、以前紹介した 条件付きコンパイル というやつです。

/*@cc_on
@if (@_jscript_version < 9)
var m = dt.match(/^(\d+-\d+-\d+)(.*?)([-+]\d+:\d+|Z)?$/);
if (m) {
  dt = m[1].replace(/-/g, '/') + m[2];
  if (m.length === 4 && 'String' === typeof m[3]) {
    var timezone = m[3] === 'Z' ? '+0000'
    : m[3].replace(':', '');
    dt = dt + timezone;
  }
}
@end
@*/

こういうバッドノウハウが必要なくなる日が早く来て欲しいですね。Windows で IE10 が標準環境となるまでは難しいかな?

コメントを残す