SHOJI's Code
 仕事や趣味で書いた各種言語のプログラミングコード(エクセルVBA,PHP,C/C++/C#,JavaScript等)、その他雑記。
2017.10<<123456789101112131415161718192021222324252627282930>>2017.12
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

GetLocalTime()(あるいはGetSystemTime())という関数がある。現在時刻を取得してSYSTEMTIME構造体に返す関数だ。構造体としてはミリ秒単位までの精度があるが、実際には15ミリ秒程度の精度になる。

仕事でミリ秒単位で時刻を取得する必要があり、どうしようか考えて作ったのが以下のコード。
void PASCAL now(SYSTEMTIME *t)
{
static DWORD start;
DWORD tick;

if( t == NULL )
{
SYSTEMTIME st;
int s;

// 秒が変わる瞬間(0ミリ秒)のタイミング
for(GetLocalTime(&st),s=st.wSecond;s==st.wSecond;GetLocalTime(&st));
start = timeGetTime(); // マルチメディアタイマのカウントカウント値を保持する
}
else // 時刻の取得
{
DWORD msec;

GetLocalTime(t); // 日時の取得(このときのミリ秒は分解能が15msec程度)
msec = ((tick=timeGetTime()) - start) % 1000; // ミリ秒部分を取得(このタイマの分解能は1msec)

if( msec >= 1000 - _MAX_TIME_DIFF && t->wMilliseconds <= _MAX_TIME_DIFF )
{
// マルチメディアタイマは秒替り前で、日時は秒替り後
start = tick - t->wMilliseconds; // 基準時刻を補正
msec = t->wMilliseconds; // ミリ秒部は変えない
}
else if( msec <= _MAX_TIME_DIFF && t->wMilliseconds >= _MAX_TIME_DIFF )
{
// マルチメディアタイマは秒替り後で、日時は秒替り前
start = tick - t->wMilliseconds; // 基準時刻を補正
msec = t->wMilliseconds; // ミリ秒部は変えない
}
t->wMilliseconds = (WORD)msec; // ミリ秒を更新
}
}


はじめに now(NULL) として、秒替りの基準時刻を設定してから、マルチメディアタイマ(timeGetTime())を使ってミリ秒部を補正している。先立ってtimeSetPeriod()で分解能を設定しなければならないし、winmm.libをリンクする必要がある。開始からのtimeGetTime()との差の1000で割った余りをミリ秒として使っているが、タイミング的に先にGetLocalTimeが次の秒にいってしまったり、先にtimeGetTimeが0に戻ったりするケースもあるので、補正するようにしているが、この部分がちょっと気にいらない(>_<)

テーマ:プログラミング - ジャンル:コンピュータ
コメント
この記事へのコメント
コメントを投稿する

管理者にだけ表示を許可する
トラックバック
この記事のトラックバックURL
この記事へのトラックバック
copyright © 2004-2006 SHOJI, Powered By FC2ブログ all rights reserved.
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。