ゴール: ローカル時間とUTC時間のオフセットを求め、以下のフォーマットでURLを作成する。
URLの例。/Actions/Sleep?duration=2002-10-10T12:00:00−05:00
このフォーマットはW3Cの勧告に基づいています。 http://www.w3.org/TR/xmlschema11-2/#dateTime
ドキュメントには
例えば、2002-10-10T12:00:00-05:00(2002年10月10日の正午。 2002年10月10日の正午(米国の東部標準時と同様、中部夏時間)は は、2002-10-10T12:00:00Zから5時間後の2002-10-10T17:00:00Zに相当します。
私の理解では、new Date()でローカル時間を求め、getTimezoneOffset()関数で差を計算し、それを文字列の最後に添付する必要があります。
1.ローカルタイムの取得(フォーマット
var local = new Date().format("yyyy-MM-ddThh:mm:ss"); //today (local time)
出力。
2013-07-02T09:00:00
2.UTC時刻を1時間単位で取得する
var offset = local.getTimezoneOffset() / 60;
出力。
7
3.Construct URL(タイムパートのみ)
var duration = local + "-" + offset + ":00";
出力:。
2013-07-02T09:00:00-7:00
上記の出力は、私の現地時間が2013/07/02 9amで、UTCとの差が7時間であることを意味します(UTCは現地時間より7時間進んでいます)。
ここまでは動作しているように見えますが、**もしgetTimezoneOffset()が-120のような負の値を返したらどうでしょうか?
W3Cのドキュメントを見てもわからないので、このような場合のフォーマットはどのようになっているのか気になります。よろしくお願いします。
以下のようにすれば、すべてのブラウザで正常に動作するはずです(@MattJohnson氏のご助言に感謝します)。
Date.prototype.toIsoString = function() {
var tzo = -this.getTimezoneOffset(),
dif = tzo >= 0 ? '+' : '-',
pad = function(num) {
var norm = Math.floor(Math.abs(num));
return (norm < 10 ? '0' : '') + norm;
};
return this.getFullYear() +
'-' + pad(this.getMonth() + 1) +
'-' + pad(this.getDate()) +
'T' + pad(this.getHours()) +
':' + pad(this.getMinutes()) +
':' + pad(this.getSeconds()) +
dif + pad(tzo / 60) +
':' + pad(tzo % 60);
}
var dt = new Date();
console.log(dt.toIsoString());
getTimezoneOffset()
は、参照した仕様で要求されている形式とは逆の符号を返します。
このフォーマットは,ISO8601,より正確にはRFC3339としても知られています。
このフォーマットでは、UTCはZ
で表され、その他のフォーマットはUTCからのオフセットで表されます。 意味はJavaScriptと同じですが、引き算の順序が逆なので、結果は逆の符号になります。
また、ネイティブのDate
オブジェクトにはformat
というメソッドはありませんので、1の関数はライブラリを使って実現しないと失敗します。 このドキュメント]3を参照してください。
もしこのフォーマットを直接扱えるライブラリを探しているのであれば、moment.jsを試してみることをお勧めします。 実際、これはデフォルトのフォーマットなので、単純にこうすればいいのです。
var m = moment(); // get "now" as a moment
var s = m.format(); // the ISO format is the default so no parameters are needed
// sample output: 2013-07-01T17:55:13-07:00
これは十分にテストされた、クロスブラウザ対応のソリューションであり、他にも多くの便利な機能があります。
これは、クライアントのタイムゾーンのための私の関数で、軽量でシンプルです。
function getCurrentDateTimeMySql() {
var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds
var localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0, 19).replace('T', ' ');
var mySqlDT = localISOTime;
return mySqlDT;
}