MongoDBにおけるISODateの実装を調べてみた
> ISODate;
function (isoDateStr) {
if (!isoDateStr) {
return new Date;
}
var isoDateRegex = /(\d{4})-?(\d{2})-?(\d{2})([T ](\d{2})(:?(\d{2})(:?(\d{2}(\.\d+)?))?)?(Z|([+-])(\d{2}):?(\d{2})?)?)?/;
var res = isoDateRegex.exec(isoDateStr);
if (!res) {
throw "invalid ISO date";
}
var year = parseInt(res[1], 10) || 1970;
var month = (parseInt(res[2], 10) || 1) - 1;
var date = parseInt(res[3], 10) || 0;
var hour = parseInt(res[5], 10) || 0;
var min = parseInt(res[7], 10) || 0;
var sec = parseFloat(res[9]) || 0;
var ms = Math.round(sec % 1 * 1000);
sec -= ms / 1000;
var time = Date.UTC(year, month, date, hour, min, sec, ms);
if (res[11] && res[11] != "Z") {
var ofs = 0;
ofs += (parseInt(res[13], 10) || 0) * 60 * 60 * 1000;
ofs += (parseInt(res[14], 10) || 0) * 60 * 1000;
if (res[12] == "+") {
ofs *= -1;
}
time += ofs;
}
return new Date(time);
}
最後がreturn new Date(time)となっているので、これはつまりDateオブジェクトを生成するただのユーティリティ関数なんですね。ISODateの呼び出し方法
ISODate関数を使ってオブジェクトを生成するには、次のようなルールがあることがわかります。- 年月日の間のハイフン"-"は、あってもなくても同じ。
- 年月日と時間を区切るのは、"T"または" "どちらもでよい。
- 自分秒を区切る":"は、あってもなくても同じ
- ミリ秒を表現する場合は、秒の後に".123"のように書く。
- 日本標準時でオブジェクト生成する場合は、最後に'+09:00'と書く。
# 日付と時間の区切りはT,空白のどちらか (区切りなしはダメ)
ISODate('2011-12-23T04:41:00')
ISODate('2011-12-23 04:41:00')
# 年月日の区切りはあってもなくても同じ
ISODate('2011-1223 04:41:00');
ISODate('201112-23 04:41:00');
ISODate('20111223 04:41:00');
# 時分秒の区切りはあってもなくても同じ
ISODate('2011-12-23 0441:00');
ISODate('2011-12-23 04:4100');
ISODate('2011-12-23 044100');
# 区切りを全部省略できる
ISODate('20111223 044100');
# ミリ秒を表現する場合はこう (ただし有意なのは1ms単位まで)
ISODate('20111223 044100.000000');
# 日本標準時の表現でオブジェクト生成する
ISODate('2011-12-23 13:41:00+09:00');
世界標準時と日本標準時について
下記の2つの表現が等価であると覚えておけばよいでしょう。ISODate('2012-01-01 00:00:00')
ISODate('2012-01-01 09:00:00+09:00')
実際、MongoShellで比較してみると同じ値であることがわかります。
> var t1 = ISODate('2012-01-01 00:00:00');
> var t2 = ISODate('2012-01-01 09:00:00+09:00');
> t1.toString() === t2.toString();
true
イギリス人が「ハッピーニューイヤー」の花火を打ち上げている瞬間に、日本人が元旦朝9時のお雑煮を食べている絵を想像すると、 覚えやすいと思います。
まとめ
MongoDBのISODateの実体について掘り下げてみました。MongoShellを直接叩くとき、このような知識があるとちょっと便利ですね。
カテゴリ:
MongoDB
JavaScript