2011-02-04 8 views
2

私は複数のタイムゾーンを扱うExtJSアプリを持っています。サーバー上の時刻はUTCに格納されます。日時をグローバルに調整する

すべての日付は、サーバーに送信する際にISO8601としてシリアル化されるため、UTCの日付は正しいです。

これは問題なく動作しますが、ユーザーのシステム時間が間違っていることが起こります。理想的には、サーバー時刻を使用してこれを修正したいと思います。

私がしたくないことは、新しいDateインスタンスを作成して新しいオブジェクトごとに時間を調整するすべてのコードをハックすることです。それは多くの重複を意味するでしょう。

すべての日付インスタンスの時刻を1回調整する方法はありますか?

+0

これはjavascriptでどのように行うことができません。解決策は、時間を印刷する必要があるたびに新しい値を割り当てる一時的なDateオブジェクトを持つことです。アラーム(tempDate.setTime(currentDate.getTime()+調整))と同様です。 – BiAiB

+1

@BiAiB:ネイティブの「Date」オブジェクトをあなた自身のものに置き換えることができます。 [私の答え](http://stackoverflow.com/questions/4899675/javascript-adjust-date-time-globally/4900737#4900737)を参照してください。 – josh3736

答えて

3

もちろん可能です。単にデフォルトのDateオブジェクトを自分のものに置き換えてください。ここでは大まかな実装です:

(function() { 

function adjust(d) { 
    // Here's where you can make whatever adjustments you want. 
    // This will be called each time a new Date object is first created. 
    // This example will add an hour to every Date object. 
    d.setHours(d.getHours()+1); 
    return d; 
} 

var _Date = Date; // Hide the native Date object in our closure... 

Date = function(y, M, d, h, m, s, f) { // ...and replace the global version with our own. 
    var newDate; 
    // Valid Date constructors: 
    // Date() - current system time 
    // Date(milliseconds) - milliseconds since the UNIX epoch (1 Jan 1970 00:00:00 UTC) 
    // Date(dateString) 
    // Date(year, month, day, hours, minutes, seconds, milliseconds) 
    switch (typeof y) { 
     case 'string': 
      newDate = new _Date(y); 
      break; 
     case 'number': 
      // Unfortunately, we can't just `.apply(this, arguments)` since we're using the `new` operator. 
      if (typeof M == 'number') 
      if (typeof d == 'number') 
      if (typeof h == 'number') 
      if (typeof m == 'number') 
      if (typeof s == 'number') 
      if (typeof f == 'number') newDate = new _Date(y, M, d, h, m, s, f); 
      else newDate = new _Date(y, M, d, h, m, s); 
      else newDate = new _Date(y, M, d, h, m); 
      else newDate = new _Date(y, M, d, h); 
      else newDate = new _Date(y, M, d); 
      else newDate = new _Date(y, M); 
      else newDate = new _Date(y); 
      break; 
     default: 
      newDate = new _Date(); 
    } 
    return adjust(newDate); 
}; 
Date.UTC = function(y, M, d, h, m, s, f) { throw new Error('Not implemented.'); }; 
Date.now = function() { return new Date(); }; 
Date.parse = function(d) { return _Date.parse(d) }; 
})(); 

テスト:

console.log(new Date().toString()); 
console.log(new Date(1234).toString()); 
console.log(new Date('2011-02-04 11:00:00').toString()); // IE's date string parser won't recognize this format, but Chrome's does. Use DateJS if necessary. 
console.log(new Date(2011, 1, 4, 11, 0, 0, 0).toString()); 

...出力:考慮すべき

 
Fri Feb 04 2011 13:04:29 GMT-0500 (Eastern Standard Time) 
Wed Dec 31 1969 20:00:01 GMT-0500 (Eastern Standard Time) 
Fri Feb 04 2011 12:00:00 GMT-0500 (Eastern Standard Time) 
Fri Feb 04 2011 12:00:00 GMT-0500 (Eastern Standard Time)

もの:

  • あなたが大規模なサードを使用している、特に以来誰もが知っているパーティーのライブラリ - どのような相互依存関係がDateの作品にあるのかあなたは奇妙なことがあります。がんばろう。
  • このコードの配置は重要です。それはDateオブジェクトのprototypeDateJS、例えば)が、何を修正Dateをインスタンス化しようとすると任意のコードの後を含める必要があります。これが実行された後にDate.prototypeを変更するものは動作しません。
  • ChromeとIEで最低限のテストを行いました。仕事をしているようだ。
  • Chromeのデベロッパーツールでは、通常、表示される(コンソールと時計式で)Dateが表示されますが、これを有効にすると、「日付」だけが表示されます。
+0

ああ、これは私が試したことの1つ、デコレータのような解決策に似ています。私はあなたが "this"に値を代入するのではなく、インスタンスを返すことができますが、わかりませんでした。これはオブジェクトリテラルでもうまく動作する(しばしば使用される)からです。 – John

+0

@ジョン:まあ、あなたが知ったと確信しているように[これは[this'に割り当てるのは誤りです](http://bclary.com/2004/11/07/#a-10.1.7) - 実行コンテキスト内では不変です。 – josh3736

+0

実際、NetBeansはそれを試してみる前にそれを選んでいました。私が値を割り当てることを意味する(メソッドを委任する)場合は "this"。基本的に、すべてのメソッド呼び出しをデコレータのような複合メンバに委譲します。いずれにしてもうまくいきませんでした。私はすぐにあなたの解決策を試してみましょう。 – John

0

これはjavascriptでは実行できません。クライアントマシンの日付/時刻を調整するには、kernel32.dllのsetLocalTimeまたはsetSystemTimeへのp/invoke呼び出しを行う必要があります。これを行うには、ブラウザのサンドボックスの外部にアクセスする必要があります。 あなたはこの違いにいくつかのしきい値差をテストし、それがあまり大きくなければ無視します。それ以外の場合はサーバー時間を使用します。

+0

私は彼が実際にクライアントマシンのシステム時間を変更したいとは思わない。むしろ、サーバ時間とクライアント時間との間のスキューを動的に調整しようとしているように見えます(エラーの範囲内で、明らかに)。 – josh3736

関連する問題