JavaScriptで、W3C-DTF形式文字列をDateオブジェクトへ変換する関数
一応、タイムゾーンの違いも計算するものを…¢( ・・)ノ゜ポイ
ちなみに、関数名は何となく"JSON.parse"にあわせた作りで(..;)
var g = g || {};
g.date = g.date || {};
g.date.W3CDTF = {};
/**
* W3C-DTFフォーマット文字列を分割するための正規表現
*/
g.date.W3CDTF.regexp = new RegExp("^(\\d{4})-?(\\d{2})?-?(\\d{2})?T?(\\d{2})?:?(\\d{2})?:?(\\d{2})?(\\.\\d+)?(\\+|-|Z)?(\\d{2})?:?(\\d{2})?$");
/**
* W3C-DTFフォーマット文字列からDateオブジェクトへ変換します。
* @param {string} text W3C-DTFフォーマット文字列
* @return {Date} Dateオブジェクト
*/
g.date.W3CDTF.parse = function (text) {
var splitted;
var year, month, day, hour, minute, second, millisecond;
var date;
var timezoneOffset, machineTimezoneOffset, dataTimezoneOffset;
// 正規表現で分割
splitted = text.match(g.date.W3CDTF.regexp);
// 各値に振り分け
year = splitted[1];
month = splitted[2] ? parseInt(splitted[2], 10) - 1 : 0;
day = splitted[3] ? parseInt(splitted[3], 10) : 1;
hour = splitted[4] ? parseInt(splitted[4], 10) : 0;
minute = splitted[5] ? parseInt(splitted[5], 10) : 0;
second = splitted[6] ? parseInt(splitted[6], 10) : 0;
millisecond = splitted[7] ? parseFloat(splitted[7]) * 1000 : 0;
// Dateオブジェクトを生成
date = new Date(year, month, day, hour, minute, second);
date.setMilliseconds(millisecond);
// タイムゾーンの違いを計算(単位は"分")
machineTimezoneOffset = date.getTimezoneOffset();
if (splitted[8]) {
switch (splitted[8]) {
case '+':
dataTimezoneOffset = -(parseInt(splitted[9], 10) * 60 + parseInt(splitted[10], 10));
break;
case '-':
dataTimezoneOffset = parseInt(splitted[9], 10) * 60 + parseInt(splitted[10], 10);
break;
case 'Z':
dataTimezoneOffset = 0;
break;
}
timezoneOffset = machineTimezoneOffset - dataTimezoneOffset;
// タイムゾーンの違いを吸収する
date.setTime(date.getTime() - timezoneOffset * 60 * 1000);
}
return date;
};
W3C-DTFは「1997-07-16T19:20:30+01:00」みたいやつ。 確かC#(.NET)のDateTimeを.ToString()したらこんな文字列になった気がする。。 W3C-DTF形式の日付文字列に関する詳細はW3Cのサイトを参照していただくとして…(^_^;)
正規表現で分割された結果は次のような感じになる…ハズ (というか、デバッグ中のキャプチャだからなってる)
この正規表現がよく分かってないまま、何となく動くものできたから放置プレー中www 配列の0番目に全部一致した文字列が必ず入るのがどうにかしたいけど… 「動いてるからいいや」という思いも。 あ、あと、たぶん正規表現があまり高速ではない気がする… なにせ「?」が多いから(..;)
いったん、ここまでかな… この関数があってるかどうかなんて分からないから、やっぱり、単体テストとかしてみたい。 QUnitもいいけど…jasmine使ってみたいなぁ…
最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!