12

私は、顧客に表示している情報でリアルタイムに更新されるキャンバスグラフに取り組んでおり、時計のDST変更の準備を進めていました。私たちの要件の1つは、時計が切り替わったときに顧客がページを更新しなくても、グラフが通常どおり機能し続けることです。

この問題に取り組んでいるときに、Firefoxのこのバグについて知りました。

https://bugzilla.mozilla.org/show_bug.cgi?id=127246

基本的に、JavaScriptのDate()オブジェクトは、ブラウザ/タブを閉じずにシステム時刻を変更した場合、Firefoxで更新されません。また、システムクロックを使用してAPIをクエリしているため、これはかなり大きな問題です。

チケットはまだ「NEW」とマークされているため、修正されていないと思います。また、コードの別の部分ではなく、これが問題の原因であると確信しています。システムの現在の時刻を取得するにはどうすればよいですか。ページを更新せずにFirefoxで変更した後のクロック?

参考までに、私が使用しているFirefoxのバージョンは19.0.2です。

前もって感謝します

システム時計を12:00に設定し、Webアプリを開きます...

var currentHour = new Date().getHours() //returns 12

Webアプリを再度開かずにシステム時計を13:00に設定します。

var currentHour = new Date().getHours() //returns 12
4

5 に答える 5

9

とにかく正しい日付/時刻を設定するためにクライアント側に頼ることはできません。私が考えることができる唯一の回避策は、サーバーなどの別のソースから現在の時刻を要求することです。

独自のサーバーにバグを報告したくない場合は、ある種のTime APIなどのタイムスタンプを返すパブリックAPIや、eBayのClientAlertsAPIなどの信頼できる稼働時間のサービスを見つけることができます。

http://clientalerts.ebay.com/ws/ecasvc/ClientAlerts?callbackname=hello&callname=GetPublicAlerts

hello({"Timestamp":"2013-03-22T14:43:21.757Z","Ack":"Failure","Errors":[{"ShortMessage":"Missing required input element.","LongMessage":"Required input element is missing from the request.","ErrorCode":"1.19","SeverityCode":"Error","ErrorParameters":[{"Value":"ChannelDescriptor","ParamID":"0"}],"ErrorClassification":"RequestError"}],"Build":"E809_CORE_BUNDLED_15739296_R1","Version":"809"});

すべてを無視して、UTCタイムスタンプを取得します。本当に必要のないデータのために、サーバーから地獄をぶち壊していないことを確認してください!

于 2013-03-22T14:49:47.710 に答える
5

Webワーカーを使用する

Sergiu Toarcaの回答のように新しいウィンドウを作成する代わりに、更新が必要になるたびに新しいWebワーカーを作成します。Date()Firefoxは、新しいWebワーカーが生成されるたびにオブジェクトを更新します。

function currDate() {
    var blob = new Blob([""]),
        blobURL = window.URL ? window.URL.createObjectURL(blob) : window.webkitURL.createObjectURL(blob),
        worker = new Worker(blobURL);
    worker.terminate();
    return new Date();
}

Date()通常のオブジェクトのように使用できます。

currDate().getHours(); // Gives you an updated hour

DEMO(Firefox 19で動作)を参照してください。

于 2013-03-26T21:21:17.547 に答える
3

この問題には簡単な(しかし非常にハッキーな)回避策があります。新しいウィンドウを作成し(何らかの理由で現在のウィンドウのキャッシュをリセットします)、そこから日付を取得して、すぐにウィンドウを閉じることができます。

var getRealDate = function() {
    var w = window.open();
    var ret = new Date();
    w.close();
    return ret;
};

jsfiddleで動作することを確認してください。ボタンをクリックしてからタイムゾーンを変更し、もう一度ボタンをクリックすると、更新された値が表示されます。

注:Firefox19でのみテストされています

于 2013-03-27T07:58:13.237 に答える
2

キャンバスのリアルタイム更新について話しているときは、Webソケットの使用など、ある種のプッシュテクノロジー、またはAJAXロングポーリングなどの偽のプッシュテクノロジーを使用していると思います。

ただし、とにかくクライアント側の時刻に依存することはできないので(他の回答で述べたように)、リアルタイムプッシュデータパッケージを使用して現在の時刻を含めてみませんか?

このようにして、1つの石で2羽の鳥を殺すことができます(武道の表現については申し訳ありませんが、それは彼らが言う方法です;-)):

  • 信頼できる中央時計が1つあります。それは、サーバーです。
  • 既存のデータ更新インフラストラクチャを利用し、他に何かを追加する必要はありません。
  • クライアントは自分の時計を好きなように設定でき、常に正しいデータになります。

クライアントが行う必要があるのは、最初に存在するタイムゾーンを取得してから、サーバーによって配信されているタイムゾーンに差を加算または減算することだけです。たとえば、クライアントがUTC + 1で、サーバーがUTC + 4の場合、サーバーが配信する各タイムスタンプから3時間を引くだけです。

DSTの変更は1年に2回しか表示されないため、これをクライアントにハードコーディングして、2つの異なる加算/減算アルゴリズムを使用することもできます。サーバーが送信するタイムスタンプの日付部分に応じて、どちらを使用するかを決定できます。

このようにして、すべての問題を解決する必要があります。これはすべてのブラウザーで機能し、クライアントの時間設定に依存しません。

お役に立てれば :-)

于 2013-03-26T19:31:32.127 に答える
1

私が(彼の質問とコメントに書かれていることに基づいて)行った次の仮定が正しいことを考えると、OPの特定の状況に対する非常に単純な解決策は次のとおりです。

  • グラフは1人の顧客のみを対象としています
  • グラフは主にFirefoxに読み込まれます(同じ参照バグがあるバージョン)
  • お客様のマシンはすべてGMTに基づいています(時計が変わるとBSTになります)
  • 機械時計は適度に正確です
  • 顧客はマシンの時計を変更するつもりはありません。

上記が当てはまる場合(おそらくすべてではない)、これは非常に簡単になります。本当に心配するのはGMTとBSTの2つのタイムゾーンだけなので、次のように例を適応させることができます。

ロード時/グラフの初期化時にこのコードを追加します。

// given a date object, returns the actual hour (works for GMT/BST only)
var getDisplayHour = (function() {
  var initiallyGMT = (new Date().toString().indexOf('BST') === -1);
  return function ( date ) {
    var isGMT = (date.toString().indexOf('BST') === -1);
    var offset = initiallyGMT - isGMT;
    return date.getHours() + offset;
  }
})();

システム時計を12:00に設定し、Webアプリを開きます...

var currentDisplayHour = getDisplayHour( new Date() ); // returns 12

Webアプリを再度開かずにシステム時計を13:00に設定します。

// the referenced bug keeps the same time, but it successfully changes the time zone, so:
var currentDisplayHour = getDisplayHour( new Date() ); // returns 13

MacおよびWindows7のFF19.0.0.2でテスト済み。

注: OPの問題を実際に再現することはできず、引用されたユースケースを考慮すると、これらの回避策のいずれかが必要かどうかさえわかりません。OPのユースケースのより正確なテストには、時間とゾーンの両方の変更が含まれると予想される場合があります。たとえば、12:00-> 13:00だけでなく、12:00 GMT->13:00BSTです。DST切り替えのさらに正確なシミュレーションは、時計を2013-03-31 00:59:00 GMTに設定し、を確認しnew Date().getHours()、数分待ってから、もう一度時間を確認することです。

しかし、私が言ったように、私は引用されたバグを自分で再現することができなかったので、私は間違いなく間違っている可能性があります(その場合、私はこの答えを修正または削除します)。

とにかく、これが役立つことを願っています!

于 2013-03-28T23:47:09.003 に答える