時間を正確に計る

赤字:JavaScriptの命令や重要なタグ/青字:用途に応じて変更する部分/緑字:変更可能な変数名やユーザー関数名


戻る

実例

例文

<form name="form_count"><input name="counter" type="text" size="12"></form>

<script type="text/javascript">
timer_set(); //タイマー動作開始

function timer_set() {
	//初期値
	timer_fix = 2; //小数点以下の桁数(*1)

	//開始時刻
	var now = new Date(); //(*2)
	//1/1000秒単位
	nt = now.getTime(); //(*3)
	
	//タイマー始動
	timerID = setInterval('timer_output()',1000/Math.pow(10,timer_fix)); //(*4)
}

function timer_output() {
	//現在時刻
	var now = new Date(); //(*5)
	//1/1000秒単位
	mt = now.getTime(); //(*6)
	
	//開始時刻と現在時刻の差を出力
	document.form_count.counter.value = count_format((mt-nt)/1000,timer_fix); //(*7)
}

function count_format(sec,fix) {
	//sec=秒数 fix=小数桁数
	var ts = sec.toFixed(fix); //小数点以下の調整
	var tm = Math.floor(ts / 60); //秒数切り捨て
	ts = ts % 60; //60秒未満の秒数
	var th = Math.floor(tm / 60); //分の切り捨て
	tm = tm % 60; //60分未満の分数
	//表示の整形
	if (ts < 10) ts = "0" + ts;
	if (tm < 10) tm = "0" + tm;
	if (th < 10) th = "0" + th;
	return th + ":" + tm + ":" + ts; //文字列を返す
}
-->
</script> 

解説

1秒毎にタイマーを呼び出すと、OSやブラウザが他の処理に時間を取られて時間が遅れることがあります。長時間動作させて、なおかつ1/10秒や1/100秒単位で時間を計るとなると誤差は大きく影響してきます。

そこで、タイマーをカウント式ではなく、開始時の時間と表示する瞬間の時間の差を計算することで、その時点での正確な時間を表示します。

スクリプトはユーザー関数timer_setを呼び出すことから始まります。

(*1)変数timer_fixには、表示する小数点以下の桁数を指定します。これに連動してタイマーの動作も切り替わります。
設定できる値は0~4です。1秒単位から1/1000秒単位まで表せます。

(*2)変数nowに開始時刻を設定します。

(*3)変数ntに開始時刻を1/1000秒単位に変換した数値を入れます。

(*4)タイマーを始動します。動作の単位は1/1000秒単位ですので、変数timer_fixが0の時は1000/1、1の時は1000/10となります。

タイマーの表示はユーザー関数timer_outputで行っています。

(*5)変数nowに表示する時点の時刻を取得します。

(*6)変数mtに現在時刻を1/1000秒単位に変換した数値を入れます。

(*7)ユーザー関数count_formatで書式を整えたカウントを出力しています。ここで、
1つ目の引数で現在のカウントを計算しています。現在時刻から開始時刻を差引、単位を1秒に変換します。
2つ目の引数で小数点以下の桁数を指示するため変数timer_fixを指定しています。

ユーザー関数count_formatについてはこちらを参照してください。

応用 - マイナスの表示

2つの時間を差し引いて表示するとき、結果がマイナスになることもあります。
例えば、目標の時間まで計測するタイマーの場合で、目標までの残り時間はプラスですが、目標時間を過ぎるとマイナスになります。また、逆に作業予定時間を決めて、それより前の時間ならマイナス、時間を過ぎてしまったらプラスという表現も考えられます。

このような時間差を正しく、分かりやすく表示するようにします。
変更箇所を赤字にします。

(省略)

function count_format(sec,fix) {
	//sec=秒数 fix=小数桁数
	var pm = "+";
	if (sec < 0) {
		pm = "-";
		sec = Math.abs(sec); //絶対値
	}
	var ts = sec.toFixed(fix); //小数点以下の調整
	var tm = Math.floor(ts / 60); //秒数切り捨て
	ts = ts % 60; //60秒未満の秒数
	var th = Math.floor(tm / 60); //分の切り捨て
	tm = tm % 60; //60分未満の分数
	//表示の整形
	if (ts < 10) ts = "0" + ts;
	if (tm < 10) tm = "0" + tm;
	if (th < 10) th = "0" + th;
	return pm + th + ":" + tm + ":" + ts; //文字列を返す
}
-->
</script> 

変数secにはマイナスの数値が入ってくることを想定し、マイナスの場合に変数pmの中を「-」記号にして、次に絶対値を計算させて変数secからマイナス表記をなくしています。
この絶対値の計算を入れておかないと、変数th、変数tm、変数tsにマイナスのまま値が引き継がれてしまいます。

もし、「+」表示がいらない場合は、最初の追加行を「var pm = "";」にしてください。

戻る