Webアプリケーションを書いていると、(サーバー側で)すべてのデータタイムをUTCタイムスタンプとしてDBに保存することに意味があります。
しかし、JavaScriptではタイムゾーンの操作があまりできないことに気づいたときは驚きました。
そこで、Dateオブジェクトを少し拡張してみました。この機能は意味があるのでしょうか?基本的に、私がサーバーに何かを送信するたびに、それはこの関数でフォーマットされたタイムスタンプになります...。
ここで何か大きな問題があると思いますか?あるいは別の角度からの解決策があるかもしれません。
Date.prototype.getUTCTime = function(){
return new Date(
this.getUTCFullYear(),
this.getUTCMonth(),
this.getUTCDate(),
this.getUTCHours(),
this.getUTCMinutes(),
this.getUTCSeconds()
).getTime();
}
私には少し複雑に思えるのですが。また、性能についてもあまり自信がありません。
1.この方法で作成された日付はローカルのタイムゾーンを使用するため、作成された日付は正しくありません。特定の日付オブジェクトにタイムゾーンを設定するには、タイムゾーンを含む日付文字列から日付オブジェクトを作成します。(Androidの古いブラウザでは動作に問題がありました)。
2.2. getTime()
は単なる秒ではなくミリ秒を返すことに注意してください。
UTC/Unixのタイムスタンプの場合は、以下のようにすれば十分です。
Math.floor((new Date()).getTime() / 1000)
これは現在のタイムゾーンのオフセットを結果に反映させます。文字列表現の場合は、David Ellis'の回答が有効です。
明確にするために
new Date(Y, M, D, h, m, s)
その入力は local time として扱われます。もし UTC time が渡された場合、結果は異なります。観察してみましょう(私は今、GMT +02:00にいて、07:50になっています)。
> var d1 = new Date();
> d1.toUTCString();
"Sun, 18 Mar 2012 05:50:34 GMT" // two hours less than my local time
> Math.floor(d1.getTime()/ 1000)
1332049834
> var d2 = new Date( d1.getUTCFullYear(), d1.getUTCMonth(), d1.getUTCDate(), d1.getUTCHours(), d1.getUTCMinutes(), d1.getUTCSeconds() );
> d2.toUTCString();
"Sun, 18 Mar 2012 03:50:34 GMT" // four hours less than my local time, and two hours less than the original time - because my GMT+2 input was interpreted as GMT+0!
> Math.floor(d2.getTime()/ 1000)
1332042634
また、getUTCDate()
はgetUTCDay()
の代わりにはならないことに注意してください。これは、getUTCDate()
は月の日を返すのに対し、getUTCDay()
は週の日を返すからです。
また、getTimezoneOffsetやgetTimeを利用して行うこともできます。
x = new Date()
var UTCseconds = (x.getTime() + x.getTimezoneOffset()*60*1000)/1000;
console.log("UTCseconds", UTCseconds)
実際、jsのDate値はC#のDateTimeオブジェクトよりもはるかに優れていると思います。C#のDateTimeオブジェクトはKindプロパティを持っていますが、基本となるタイムゾーンは厳密には存在せず、UTCではない2つの時間やローカルではない時間を変換する場合、タイムゾーンの変換を追跡するのは困難です。jsでは、すべてのDate値には基礎となるUTC値があり、オフストやタイムゾーンの変換にかかわらず、その値は受け渡され、知ることができます。Dateオブジェクトに関する私の最大の不満は、ブラウザの実装者が選択した未定義の動作が多く含まれていることで、仕様書を読むよりも試行錯誤しながらjsで日付を扱う人を混乱させてしまいます。iso8601.jsのようなものを使えば、Dateオブジェクトの単一の実装を定義することで、この様々な挙動を解決することができます。
デフォルトでは、仕様書では以下のようなISO 8601拡張日付フォーマットで日付を作成できることになっています。
var someDate = new Date('2010-12-12T12:00Z');
そのため、この方法で正確なUTC時間を推測することができます。
Dateの値をサーバーに返すときは、次のようにします。
someDate.toISOString();
または、ミリ秒単位のタイムスタンプ(1970年1月1日UTCからのミリ秒数)を使いたい場合は
someDate.getTime();
ISO 8601は標準規格です。日付オフセットを含めると、日付文字列の意味を混乱させることはありません。これが開発者にとって何を意味するかというと、ローカル時間の変換を自分で行う必要がないということです。ローカルタイムの値は、純粋にユーザーのために存在しており、日付の値はデフォルトでローカルタイムで表示されます。すべてのローカル時間の操作は、ユーザーに何か意味のあるものを表示したり、ユーザーの入力から文字列を変換したりするのに役立ちます。できるだけ早くUTCに変換することをお勧めしますが、jsのDateオブジェクトを使えば、簡単に変換できます。
欠点としては、クライアントのタイムゾーンやロケールを強制的に変更する機能があまりないことです(私が知っている限りでは)。これは、Webサイト固有の設定をする際に困ることになりますが、この理由は、ユーザーの設定には触れるべきではないということでしょう。
要するに、タイムゾーンの操作をネイティブでサポートしていない理由は、単にそれをしたくないからなのです。