Little Strange Software

スマホアプリの開発を行う LittleStrangeSoftware のブログです。

【JavaScript】アナログ時計、現在時刻を取得するもう一つの方法+より正確な時計を目指して(?)

 どうも!LSSです!!

 

【JavaScript】アナログ時計を作ってみました - Little Strange Software

で使用していたコードのうち、スクリプト部分についての解説を、

little-strange.hatenablog.com

に書きました。

 

そのスクリプトでは、現在時刻の取得を「Date.now()」によって「国際標準時のミリ秒」で行っていたため、時差の修正やミリ秒から時分秒への変換を行っていました。

 

…で、JavaScriptで現在時刻を取得する方法は複数あり、実はそのまま「現地時間での時・分・秒」を取り出す方法もあるんですね。

 

ミリ秒から計算する方法を採択しましたが、後者の方法を使った場合とどちらがコードが効率的か?

ちょっと比較のために書いてみる事にしました。

 

 

コード比較

Date.now()を利用したコード(元)

<script>
tokeitm=setInterval(function(){
tokein=Math.floor(((Date.now()-(new Date()).getTimezoneOffset()*60000)%86400000)/1000);
tokeih.style.transform='rotate('+(((tokein%43200)/43200)*360-90)+'deg)';
tokeim.style.transform='rotate('+(((tokein%3600)/3600)*360-90)+'deg)';
tokeis.style.transform='rotate('+(((tokein%60)/60)*360-90)+'deg)';
},1000);
</script>

 

 

new Date()とget〇〇を利用したコード(新)

<script>
tokeitm=setInterval(function(){
tokeio=new Date();
tokeih.style.transform='rotate('+((tokeio.getHours()%12+tokeio.getMinutes()/60+tokeio.getSeconds()/3600)*30-90)+'deg)';
tokeim.style.transform='rotate('+((tokeio.getMinutes()+tokeio.getSeconds()/60)*6-90)+'deg)';
tokeis.style.transform='rotate('+(tokeio.getSeconds()*6-90)+'deg)';
},1000);
</script>

 

 

スクリプト部分のみ書き出してみました。

 

うーん…。
書き方にもよるとは思いますが、「元」より「新」のほうが行が長くなってる印象もある反面、コードの内容の理解しやすさでいうと圧倒的に「新」のほうが優れているという気もします。

 

 

おまけ:時計の精度アップ?

 

コード

<style>
#tokei{
position:relative;
width:300px;
height:300px;
background-color:#eeeedd;
}
#tokeih,#tokeim,#tokeis{position:absolute;transform-origin:10px 50%;left:140px;}
#tokeih{background-color:black;width:70px;height:20px;top:140px;}
#tokeim{background-color:gray;border:3px solid black;width:120px;height:16px;top:142px;}
#tokeis{background-color:red;width:110px;height:10px;top:145px;}
#tokeic{position:absolute;background-image:radial-gradient(#00000080 40%,#00000000 50%);width:8px;height:8px;top:146px;left:146px;}
</style>
<div id="tokei">
<div id="tokeih"></div>
<div id="tokeim"></div>
<div id="tokeis"></div>
<div id="tokeic"></div>
</div>
<p>
<script>
tokeiz();
function tokeiz(){
tokeio=new Date();
tokeitm=setTimeout('tokeiz()',1000-tokeio.getMilliseconds());
tokeih.style.transform='rotate('+((tokeio.getHours()%12+tokeio.getMinutes()/60+tokeio.getSeconds()/3600)*30-90)+'deg)';
tokeim.style.transform='rotate('+((tokeio.getMinutes()+tokeio.getSeconds()/60)*6-90)+'deg)';
tokeis.style.transform='rotate('+(tokeio.getSeconds()*6-90)+'deg)';
}
</script>

 

「もしかしたら、この方が時計の誤差が少ないのでは?」
と思った方法を試してみました。

 

元のスクリプトでは、「毎回1秒ごとに、時刻を読み込んで時計の針に反映させる」という方法をとっていましたが、その場合例えば最初に動きだした時刻の末尾が「7.457秒」だと、ずっと「0.457秒」分ズレた動きを続ける事になります。

 

その「次の動作を呼び出す」部分を「setInterval(何度も繰り返す)」から「setTimeout(一度だけ次を呼び出す)」方法に変え、さらにsetTimeoutで指定する「次の呼び出しまでの待ち時間」を「1000-現在時刻のミリ秒」としました。

こうすると、前述の「7.457秒」だと次は「0.543秒後に呼び出しが行われる」事になり、毎回「時刻のミリ秒部分は0.000秒にしようとする」事になります。
(といってもスクリプトの実行にも時間はかかるので、ミリ秒レベルでいうと誤差は当然のようにあるハズではありますw)

 

より正確な「現在時刻」を目指した反面、一回の秒針の「カチ」の間隔は「1秒」からずれる事になりそうですね。

 

…この場合、どちらが「正確な時計」と言えるんでしょう?という新たな疑問もwww

 

 

 

ってなとこで、今回はこのへんで!

次回もまた、よろしくお願いします^^