-1

Windowsの高精度タイマーについて多くの質問を見てきましたが、本当に必要なのは、GetLocalTime()が提供する10〜15ミリ秒の粒度よりも正確なWindowsの時計時間を提供するものです。

既存の単純な解決策が見つからなかったので、完全に洗い流されていない独自の解決策を思いつきましたが、基本的な考え方は深夜まで機能します。ここで共有して、他の人に役立つようにします。

プログラムの起動時にアンカー時間を保存し、timeGetTime()を使用してシステムの稼働時間をミリ秒単位で取得し(1ミリ秒未満に細かく設定)、それに応じてアンカー時間を調整します。

コードが答えにあります。

4

1 に答える 1

-1

初めて実行すると、時間とティックカウントが取得されるため、同期されており、測定するものがあります。initセクションはスレッドセーフではなく、深夜に折り返されることはありませんが、以下のキャリーフォームに従って簡単に追加できます。

// this solution is limited to 49+ days of uptime
int timeinitted = 0;
SYSTEMTIME anchortime;
DWORD anchorticks; 

void GetAccurateTime(SYSTEMTIME *lt)
  {
    if (timeinitted == 0)
      { // obviously this init section isn't threadsafe. 
        // get an anchor time to sync up with system ticks. 
        GetLocalTime(&anchortime);
        anchorticks = timeGetTime();
        timeinitted = 1;
      }

     DWORD now = timeGetTime();
     DWORD flyby = now - anchorticks;

     // now add flyby to anchortime
     memcpy (lt, &anchortime, sizeof(anchortime));
     // you can't do the math IN the SYSTEMTIME because everything in it is a WORD (16 bits)
     DWORD ms = lt->wMilliseconds + flyby;
     DWORD carry = ms / 1000;
     lt->wMilliseconds = ms % 1000;
     if (carry > 0)
       {
         DWORD s = lt->wSecond + carry;
         carry = s / 60;
         lt->wSecond = s % 60;
         if (carry > 0)
           {
             DWORD m = lt->wMinute + carry;
             carry = m / 60;
             lt->wMinute = m % 60;
             if (carry > 0) // won't wrap day correctly.
               lt->wHour = (((DWORD)lt->wHour + carry)) % 24;
           }
         // add day and month and year here if you're so inspired, but remember the 49 day limit
       }
  }
于 2012-11-14T18:23:56.717 に答える