JSTの取得の誤差
塩キャラメル 2013/6/21(Fri) 00:56:36|NO.55120
JSTとPC時計とのズレを計測するために下のコードを組んだのですが誤差がひどく
起動するたびに実用に耐えられないレベルで求められる誤差が変わってしまいます
#include "mod_unixtime.as"
#include "hspinet.as"
#uselib "kernel32.dll"
#cfunc global getoptime "GetTickCount"
netinit
//サーバAから現在時間を取得
// tsa = 接続前のPCを起動してからの時間(ミリ秒)
// tea = 接続後のPCを起動してからの時間(ミリ秒)
// da = double(strmid(buf,46,14))でロードした結果から時刻部分を切り出し、-(tea-tsa)/2でネット接続でのロスを除外
// -GetNowUnixTime()でPC時計の時刻との誤差を求める
tsa = getoptime()
neturl "http://ntp-a1.nict.go.jp/"
netrequest_get "cgi-bin/jst"
repeat
netexec res
if res > 0 {
break
}
if res < 0 {
neterror estr
dialog "ERROR "+estr
stop
}
loop
netgetv buf
tea = getoptime()
nkfcnv buf, buf, "Es"
da = double(strmid(buf,46,14))-((tea-tsa)/2000)-GetNowUnixTime()
//サーバBから現在時間を取得
//手順はサーバAと同様
tsb = getoptime()
neturl "http://ntp-b1.nict.go.jp/"
netrequest_get "cgi-bin/jst"
repeat
netexec res
if res > 0 {
break
}
if res < 0 {
neterror estr
dialog "ERROR "+estr
stop
}
loop
netgetv buf
teb = getoptime()
nkfcnv buf, buf, "Es"
db = double(strmid(buf,46,14))-((teb-tsb)/2000)-GetNowUnixTime()
mes "サーバA / 通信時間:" + (tea-tsa) + "ミリ秒 誤差: " + da + "秒"
mes "サーバB / 通信時間:" + (teb-tsb) + "ミリ秒 誤差: " + db + "秒"
if ( 1.0*(da+db)/2 < 0.0 ) {
mes "" + -1.0*(da+db)/2 + "秒遅れています"
} else {
mes "" + 1.0*(da+db)/2 + "秒進んでいます"
}
http://www2.nict.go.jp/aeri/sts/tsp/JST/JST5.htmlにアクセスした時のようにほぼ誤差なく正確なズレを取得したいのですが
上のプログラムは何が原因で誤差が生じてしまっているのでしょうか?教えていただけると幸いです
参考資料・使用モジュール
TSUKABAN!様(ttp://www.no-music-no-life.net/~tsukaban/)作成の日時関連モジュールセットforHSP(mod_time_for_hsp01.zip)
アルティメット様(ttp://www.rinku.zaq.ne.jp/ultimate/)のHSPデータベース>タイム>パソコンが起動してからの時間を取得
ttp://www2.nict.go.jp/aeri/sts/tsp/link/JST.html
ttp://www2.nict.go.jp/aeri/sts/tsp/PubNtp/http.html
egachan 2013/6/21(Fri) 07:18:55|NO.55122
>double(strmid(buf,46,14))-((teb-tsb)/2000)-GetNowUnixTime()
((teb-tsb)/2000)は整数でGetNowUnixTime()は秒単位なので1秒程度の誤差が出るのは当然かと。
あと((teb-tsb)/2000)は引くのではなく足すのでは?
egachan 2013/6/21(Fri) 08:04:56|NO.55124
対応策書くの忘れてた。
応急処置的には以下みたいにすればいいのでは。
>double(strmid(buf,46,14))+(double(teb-tsb)/2000)-(GetNowUnixTime()+double(gettime(7))/1000)
あとここも修正
>if ( 1.0*(da+db)/2 > 0.0 ) {
MillkeyStars 2013/6/21(Fri) 12:01:13|NO.55136
暇つぶしな、改良スクリプト。
#include "hspinet.as"
#uselib "kernel32.dll"
#cfunc global getoptime "GetTickCount"
#uselib "crtdll.dll"
#cfunc time "time" int
netinit
tsa = getoptime()
neturl "http://ntp-a1.nict.go.jp/"
netrequest_get "cgi-bin/jst"
repeat
netexec res
if res > 0 {
break
}
if res < 0 {
neterror estr
dialog "ERROR "+estr
stop
}
loop
netgetv buf
tea = getoptime()
//ここから差分計算と表示
TimeStr = "" //←ネットデータ変換用
start_posi = instr(buf,0,"1")
end_posi = instr(buf,start_posi,"<")
memcpy TimeStr,buf,end_posi,0,start_posi
//JST文字列を実数に変換
ax = double(TimeStr)
mes "JSTのGMT値 : "+ax
//遅延計算
net_time = 0.0 + (tea - tsa)
mes "JSTネット遅延 : "+net_time+" ms"
ax += 0.0 + (0.001 * net_time)
//PCのGMT値
bx = 0.0 + time(0) + (0.001 * gettime(7))
mes "PCのGMT値 : "+bx
//差を計算
cx = 0.0 + ax - bx
mes "差時間 : "+cx+" 秒"
ネットワーク測定の場合どうしても回線依存してしまうので、誤差は最大で 200ms 以内くらいであれば
範囲内としてもいいかと。
塩キャラメル 2013/6/21(Fri) 18:31:10|NO.55144
ものすごく初歩的なミスをしてしまっていたようですね、ごめんなさい
egachan様、MillkeyStars様回答ありがとうございました!
MillkeyStars 2013/6/22(Sat) 05:23:21|NO.55156
すでに解決済みだけど、ひとつだけ。
コンピュータの時刻は、わざと遅くなるように設計されています。
その為、前回計測した時間から一日置くと、大幅にずれが生じる場合がございますので
その点も考えてみてくださいね。
当方のPCの場合、約 18時間で、4.6秒の遅れが生じる。