time
要素にdatetime
属性があったら、それを元に現在時刻からの相対日時を生成し、その内容を差し替えるスクリプトを書いていた。相対日時を得るには、ミリ秒数同士を引き算して1000で割って60以下なら~秒前、60で割って60以下なら~分前、60で割って24以下なら~時間前、24で割って30以下なら~日前、30で割って12以下なら~か月前、12で割って~年前というものをそのままコードにした。車輪だ。
const now = Date.now();
const toRelativeDate = function (then) {
let diff = 0;
if (!Number.isInteger(then)) {
return;
}
diff = parseInt((now - then) / 1000, 10);
if (diff < 0) {
return;
}
if (diff < 60) {
return diff + "秒前";
}
diff = parseInt(diff / 60, 10);
if (diff < 60) {
return diff + "分前";
}
diff = parseInt(diff / 60, 10);
if (diff < 24) {
return diff + "時間前";
}
diff = parseInt(diff / 24, 10);
if (diff < 30) {
return diff + "日前";
}
diff = parseInt(diff / 30, 10);
if (diff < 12) {
return diff + "か月前";
}
return parseInt(diff / 12, 10) + "年前";
};
Demo: Test Page for reldate.js
日本語だと複数形のことを考えなくて良いのでシンプルなコードになった。2年前以上は日時をそのまま表示したいという場合は、最初の方でdiffが一定数以上の時に抜けるようにしてやると良い。
タイムゾーンのことをまったく考えていない。Date.now()
とDate.parse()
でISO-8601をパースした時はUTCのミリ秒になるはずなので、大丈夫なんじゃないかと楽観している。また相対時刻がそもそもあやふやなので、最大24時間ずれるくらい大したこともなさそうだ。このあたりも含めて確実にしたいならMoment.jsを使うべきだろう。そうすればmoment#toNow()
などもあり、何も考える必要はなくなる。
ウェブサイト上で動かすスクリプトを昔のことは忘れて書き、Closure CompilerのJavaScriptバージョンでES5への変換と最小化を同時にやるようにし始めた。もちろんgyp依存とかでもないため、Windowsで普通に動く。いくつか小さなプロジェクトでも使ってみているが、UglifyJS2を差し替えるくらいの感覚で移行できている。ちょっと処理が遅く、最小化後のサイズも大きくはなるが、それを補って余りある簡便さだ。
規模の大きなJavaScriptコードを処理しようとするとメモリーを食い尽くすなど、パフォーマンスの点で問題がいくつかあるようだ。まだプロダクションで使うのは怖いが、小さいところではちょいちょい使っていきたい。