環境: Windows2000 VB6 SP5
私も、下の参考リンクのようなSNTPクライアントソフトを作ったのですが、
>http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200310/03100003.txt
例えば、桜時計のように、ミリ秒までできるだけ正確に設定したいと考えていま
したがスタート基準点を決める GetSystemTime でのローカル時間が約10msecの
間隔でしか取得できないことが判明しました。
( timeBeginPeriod がこのAPIでは無効 )
>http://www7.big.or.jp/~pinball/discus/vb/52103.html
そのため、Loop処理で GetSystemTime の返す時間が丁度変わるときをスタート
基準点とし、終了時は timeGetTime での経過時間を足して計算しております。
このようなLoop処理でのタイミングでなく、何か別のAPI無いか探しましたが
見つかりませんでした。
もっと良い(正確な)PCシステム時間の取得方法があれば教えていただきたいのです
が宜しくお願いいたします。
使用可能なOSに制限がありますが・・・
QueryPerformanceCounter
QueryPerformanceFrequency
なら、もっと高分解能な取得が可能ですが・・・
VB6のみでは取得は不可能かも・・・
私はC言語側で取得してVB6に渡すような
DLLを作成して使っています。
ご参考までに・・・
以上。
岡田さん、アドバイスありがとうございます。
私の知識では、QueryPerformanceCounter QueryPerformanceFrequency で
得られるのはPC起動後の秒数と思っています。
したがって、PCシステム時間(年月日は不要ですが)何時何分何秒何ミリ秒を
得たいと思っているのですが取得不能と考えていました。
API宣言の仕方や、他のAPIとの併用で私の求めたいPCシステム時間が得られる
のでしょうか?(C言語限定でしょうか?)
お手数かけますが、アドバイス頂ければ幸いです。
経過時間に違いないですが、10ミリ秒未満でナノセックオーダー
までの経過時間が取得可能ですので、現在時刻の取得と、この
QueryPerformanceCounter等でのミリ秒未満の取得を数度、繰り
返せば、現在との差と言うか、ミリ秒未満の値が取れますので
補正は可能かと・・・
ですが、64ビット長のデータになりますので、通常では、VB
で扱うに難しく、また仮にC言語で作ってもVB側で補正関数
を作った場合、はるかに処理時間がかかってしまいますので、
現実的ではありません。
補正処理までをC言語側で作成して、結果のみをVB側に返す
と言う処理にしないと、VBが貰った時点で、既にへたをした
ら、数十ミリ秒経過してしまっている・・・と言う現象もあり
えますので・・・
※ あくまで使えるマシンの場合と言う前提です。
※ NTPプログラムに関しては、私もインターネット経由で
取得して、マシンのタイムを補正するプログラムは作成し
てはおります。
ただし、醍醐味と言うか・・・テクニック的には、Pingを
数回実施し、ネットワーク遅延がどの程度あるのかを算定
し、また、NTPタイムを取得する処理時間も数度実行し
処理時間の平均等を行い、結果としてネットワーク遅延が
安定している状態の取得データのみを遅延時間を平均化し
て、セットしなおす・・・と言う処理になると思います。
ご参考までに・・・
以上。
岡田さん、早速のご返事ありがとうございます。
>までの経過時間が取得可能ですので、現在時刻の取得と、この
私はこの正確な「現在時刻の取得」の方法がわからないのですが
最初に書きましたように GetSystemTime でのローカル時間が
私の環境では約10msecの間隔でしか取得できないのです。
具体的には、ミリ秒単位の表示ですが、ループで回すとミリ秒
部分が以下のように10msecほど飛んで表示されます。
562
562
途中省略
573
573
これを、ミリ秒単位でその瞬間の時間が知りたいのです。
私の説明がわかりづらかったでしょうか?
うまく伝わっていないようなので・・・
時刻の取得は、今まで通りでよいのですヨ!
10ミリ秒未満を、QueryPerformanceCounterでその間の
補間を行うと言う意味だったのですが・・・
これでよいでしょうか?
以上。
何度もすいません。
岡田さんの説明が理解できないのです。
とりあえず、SNTPの処理ロジックや、経過時間は別にして
PC内部時計における、有る瞬間のシステム時間を知りたいのです。
(1msec程度の精度で)
具体的に、ロジックなどを例示していただけると助かるのですが・・・
岡田さんのおっしゃているのは、私のLoopでチェックしながら数字の
変化するタイミングで拾ったGetSystemTimeの時間で良いと言うことでしょうか?
私はこの方法が正しいか自身が無いので、これとは「別」の方法は無いのかを
お尋ねしているのですが。
別の方法・・・と言うものは、別の仕組みが無いことには
無理です。
あくまで、マザーボード上のカレンダータイマーの値を取得
する方法は、GetSystemTimeでよいと考えます。
ただし、マシン性能の問題で、10msec未満の精度は、VBの
みや環境の問題で無理だと考えます。
よって、高精度で高速に取得可能な別の方法で、補間すると
言う方法を考えたにすぎません。
ただ、VBの動作性能として、1msecオーダーの性格な時刻
を取得したとしても、それをVB中で利用して、次の何かを
行った時点で、多分、1msec以上のズレ(処理時間の為)が
発生してしまうように思いますので、その意味が、理解でき
ないと言うのが、私の疑問ではあります。
※ 昔は、C言語で行っても、そのC言語のコードをアセン
ブラコードで吐かせ、ステップ数やCPUのサイクル数
まで計算して、遅延を算定したことがありました。
ですが、現在は GHz にまでCPUのクロックが高速に
なり、また高級言語もかなりの大きなコードを吐くよう
になり、その微細な処理時間を、どうこう言うことが、
ほとんど無くなりました。
が、それを気にしないといけないと言う時点では、VB
での実行と言う処理時間の約束されないものを使って、
微細な点を追求しないといけないと言う部分に、いささ
かの抵抗がありました。
実際のところ、動けばOKですが、1msecオーダーでの
実証が可能か不可能かといいますと、VBで実行した
場合、多分、不可能です。動いているであろう・・・
と言うことになると思いますが、使うAPIとアルゴ
リズムで、そこまで影響しない程度に留めた・・・
と言う形で収束すると思いますが、まずは、お考えの
コードを具現化され、目標に到達されることに注力し
て下さい。
問題があるならば、またそれ以降での時点の問題です
ので・・・
以上。
>ただ、VBの動作性能として、1msecオーダーの性格な時刻
>を取得したとしても、それをVB中で利用して、次の何かを
>行った時点で、多分、1msec以上のズレ(処理時間の為)が
>発生してしまうように思いますので、その意味が、理解でき
>ないと言うのが、私の疑問ではあります。
NTPでの計算方法は判りませんが、私は最初の質問の際の別の掲示板に
示した以下の T を求めることで誤差計算をしています。
RFC-2030
Timestamp Name ID When Generated
------------------------------------------------------------
Originate Timestamp T1 time request sent by client
Receive Timestamp T2 time request received by server
Transmit Timestamp T3 time reply sent by server
Destination Timestamp T4 time reply received by client
The roundtrip delay d and local clock offset t are defined as
d = (T4 - T1) - (T2 - T3) t = ((T2 - T1) + (T3 - T4)) / 2.
この場合、起点となるOriginate Timestampに誤差があれば、いくら
所要時間 (T4-T1) を正確に求めても t は不正確になりますよね!
そのために、Originate Timestamp を1msec 程度の誤差範囲で求めたい
だけなのです。それができれば TimeGetTime で得る時間間隔も1msec
程度の精度がありますから QueryPerformanceCounter は今のところ
必要性は感じていません。
桜時計でも同じSNTPサーバーに接続して見ますとバラツキは通常1〜3
msecでたまに10msec以上の値を示しますが、私のものでも同程度に納
まってそれなりには満足しています。
この誤差バラツキはインターネット接続の応答時間のバラツキがある
ためそれ以上の精度は岡田さんの言われるように統計的処理を必要と
することも理解していますが、そのようなことは相手のSNTPサーバー
に負荷をかけるのでするべきでは無いと考えています。
( 私のものは単なる個人的PCでの時間調整ですので。)
なぜ、この質問を上げたかと言うと、起点時間の取得に私自身が自信
が持てなかったためです。
■ また、計算処理中に時間が経過(私の場合は1msec程度?)しても、
時間を修正する時点でその経過分を加算することで対応可能と思います。
なお、この質問は解答としての岡田様のご意見は
>別の方法・・・と言うものは、別の仕組みが無いことには
>無理です。
と言うことで理解できました。いろいろ有難うございました。
長くお付き合いくださりまして深くお礼申し上げます。
参考と言うわけではありませんが・・・
最近、『電波時計』と言うものがあります。
その名の通り、日本の南北2箇所で、電波による時刻あわせを
行う為の仕組みです。
インターネットは、経路や機器の事情により遅延がありますし
NTPサーバーへの負荷のこともあります。
が、電波の場合、直接自分の環境が受けることになり、遅延理
由が限りなく除去できます。
パソコン用キットも出ており、現在は、正確な時刻あわせには
有用なものです。キットにソフトも添付されていますので簡単
に動作させれると思います。
検索エンジンで『電波時計』を探してみて下さい。
以上。
たびたび、貴重な情報有難うございます。
直ぐには使えそうにありませんが、今後の参考とさせていただきます。
重ねて御礼申し上げます。
今回の質問はこれで「解決」とさせていただきます。