2011-09-01 15 views
16

JavaScriptで時間が単調増加する最善の方法は何ですか?私はJavaのSystem.nanoTime()のようなものを望んでいます。JavaScriptの時間が単調に増えていますか?

Date()は、システム時間の変更の影響を受けるため、明らかに機能しません。言い換えれば

は、私が希望することは、< = Bのために常に次のとおりです。Date()でUTC機能を使用する場合であっても、せいぜい

a = myIncreasingTime.getMilliseconds(); 
... 
// some time later, maybe seconds, maybe days 
b = myIncreasingTime.getMilliseconds(); 

、それが信じているものを返します。正しい時刻ですが、誰かが時刻を逆向きに設定した場合、Date()への次回の呼び出しではより小さな値が返されます。 System.nanoTime()にはこの制限がありません(少なくとも、システムを再起動するまで)。

変更: [2012年2月26日:報奨金を持っている元の質問に、影響を与えることを意図していない]

私は興味がない「ウォール時間」を知っているが、私が知ることに興味が経過時間は、正確にはDate()ではありません。

+0

何を意味するのですか?このコード(ブラウザ、サーバー)はどこで実行しますか? – galambalazs

+0

[W3Schools](http://www.w3schools.com/js/js_timing.asp)に類似のものが表示されます。 – undefined

+0

申し訳ありませんが、私はあまり言いませんでした。うまくいけば、私が追加したばかりの変化はより明確です。 – danorton

答えて

10

- Firefoxの15、およびwindow.performance.webkitNow(以降) - あなたはセッションでクローム20]

var a = window.performance.now(); 
//... 
var delay = window.performance.now() - a; 
+0

この機能はIE10でも利用できます。 – danorton

1

FirefoxはsetTimeoutに "delay"引数を指定します... これは、単調増加の時間カウンタを実装する方法の1つです。

var time = 0; 

setTimeout(function x(actualLateness) { 
    setTimeout(x, 0); 
    time += actualLateness; 
}, 0); 
+2

setTimeoutには最大遅延の保証はありません。パラメータは最小値のみを指定します。 setTimeoutを使用して渡された実際の時間を最終的に決定する方法はありません。 – danorton

+0

https://developer.mozilla.org/en/DOM/window.setTimeout、>>注意:Gecko 13(Firefox 13.0/Thunderbird 13.0)以前は、Geckoはコールバックルーチンに追加のパラメータを渡しました。タイムアウトの「遅れ」をミリ秒で表します。この非標準パラメータはもうパスされません、私は私の答えを更新しました – 4esn0k

4

JavaScript自体には、nanoTimeにアクセスする機能がありません。 benchmark.jsのように、Javaアプレットをロードしてその情報を取得できます。たぶん@mathiasは、そこで何をしたのかを明らかにすることができます...

7

Date()またはDate.now()を単調(ただし不正確)にすることができます。テストされていないスケッチ、:システムクロックが与えられた瞬間に戻って設定されている場合

var offset = 0; 
var seen = 0; 
function time() { 
    var t = Date.now(); 
    if (t < seen) { 
    offset += (seen - t); 
    } 
    seen = t; 
    return t + offset; 
} 

、もう時間が経過していないと表示されます(とその間隔を含む経過時間が不正確になります)が、あなたは、少なくとも意志負のデルタを持たない。セットバックがない場合、これはDate.now()と同じ値を返します。

これは、ゲームシミュレーションループを作成する場合に適しています(たとえば、time()が非常に頻繁に呼び出される場合など)。最大エラーは、コールの間隔とセットバックの時間の差です。あなたのアプリケーションが自然にそれをしないならば、ある程度のCPU時間を犠牲にして正確さを保つために、setIntervalで明示的にそれを呼び出すことができます(例えば、システムクロックによって決まらないと仮定します)。


クロックが単調性を防ぐことはできませんが、同じように望ましくない影響(例えばゲームの支出が長すぎる一度にそのシミュレーションをキャッチアップしようとしている)を持っているかもしれない前方を、設定されることも可能です。しかしながら、これはしばらくの間眠っていた機械とは特に区別できない。このような保護が必要な場合は、それだけで許容可能な進歩のための一定の閾値と、既存のものに次の条件を変更することを意味:

if (t > seen + leapForwardMaximum) { 
    offset += (seen - t) + leapForwardMaximum; 
} 

私はleapForwardMaximumが1000以上msに設定する必要があることを示唆している、のための理由例えば、Chromeは(正しくリコールすれば)バックグラウンドタブのタイマーを1秒間に1回以上発射させないように調整します。

あなたが window.performance.now()を使用することができ
+0

はい、良い点と私がもともと尋ねたように答えた。元の質問を変更して精度要件を追加しました。 – danorton

+0

元の質問には尋ねられる方法で問題ではない種類の明白なコメントですが、一部の人にとっては重要なことかもしれません。この解決策では、ユーザーが時計を設定するケースは扱いませんつまり、返された時間に大きな正のジャンプを防ぐことはできません。 –

+0

@ MarkusA。話し合う価値があると思われたので、私はそれについてのセクションを追加しました。 –

関連する問題