程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 如何計算毫秒級的時間差,計算毫秒級時間差

如何計算毫秒級的時間差,計算毫秒級時間差

編輯:C++入門知識

如何計算毫秒級的時間差,計算毫秒級時間差


計算毫秒級的時間差算是一個常見的需求吧...

 

手頭上是windows編程的項目,所以首先就想到的是GetTickCount(),但MSDN上這麼說:

寫個程序試一下吧:

1 #include <stdio.h> 2 #include <windows.h> 3 4 int main(void) 5 { 6 DWORD dwLastTime = GetTickCount(); 7 for (int i = 0; i != 10; ++i) 8 { 9 DWORD dwCurrentTime = GetTickCount(); 10 printf("GetTickCount = %ldms TimeDiff = %ldms\n", dwCurrentTime, dwCurrentTime - dwLastTime); 11 dwLastTime = dwCurrentTime; 12 Sleep(500); 13 } 14 return 0; 15 } View Code

 

可以看到,算了10次,每次偏差一般都有1ms,更有甚者,達到15ms,跟MSDN裡說的實際精度一樣。

所以,用GetTickCount()計算毫秒級的時間差是不靠譜的!

 

那下面,如何滿足我們的需求呢?

需求1:計算毫秒級別的時間差。

需求2:返回值最好是unsigned long級別的,以便與現有代碼保持兼容。

 

解決方案1:

clock_t clock(void);

這個函數返回的是從程序啟動到當前時刻所經歷的CPU時鐘周期數。將這個函數封裝一下即可:

1 #include <ctime>
2 
3 ULONG GetTickCountClock()
4 {
5     return (ULONG)((LONGLONG)clock() * 1000 / CLOCKS_PER_SEC);
6 }

測試結果:

 

解決方案2:

SYSTEMTIME FILETIME 

通過SYSTEMTIME和FILETIME,我們可以得到距離1601年1月1日凌晨所經歷的時間,單位是100納秒。

這個時間肯定是足夠精確了,但是得到的數值是一個LONGLONG,沒關系,我們可以用這個時間來校准原生的GetTickCount()。

 1 ULONG GetTickCountCalibrate()
 2 {
 3     static ULONG s_ulFirstCallTick = 0;
 4     static LONGLONG s_ullFirstCallTickMS = 0;
 5 
 6     SYSTEMTIME systemtime;
 7     FILETIME filetime;
 8     GetLocalTime(&systemtime);    
 9     SystemTimeToFileTime(&systemtime, &filetime);
10     LARGE_INTEGER liCurrentTime;
11     liCurrentTime.HighPart = filetime.dwHighDateTime;
12     liCurrentTime.LowPart = filetime.dwLowDateTime;
13     LONGLONG llCurrentTimeMS = liCurrentTime.QuadPart / 10000;
14 
15     if (s_ulFirstCallTick == 0)
16     {
17         s_ulFirstCallTick = GetTickCount();
18     }
19     if (s_ullFirstCallTickMS == 0)
20     {
21         s_ullFirstCallTickMS = llCurrentTimeMS;
22     }
23 
24     return s_ulFirstCallTick + (ULONG)(llCurrentTimeMS - s_ullFirstCallTickMS);
25 }

測試結果:

 

精度比較

每隔50ms獲取一次當前時刻,對比TimeDiff與50之間的差距,統計1000次:

1 #include <math.h> 2 3 int main(void) 4 { 5 int nMaxDeviation = 0; 6 int nMinDeviation = 99; 7 int nSumDeviation = 0; 8 9 DWORD dwLastTime = GetTickCountCalibrate(); 10 Sleep(50); 11 12 for (int i = 0; i != 1000; ++i) 13 { 14 DWORD dwCurrentTime = GetTickCountCalibrate(); 15 int nDeviation= abs(dwCurrentTime - dwLastTime - 50); 16 nMaxDeviation = nDeviation > nMaxDeviation ? nDeviation : nMaxDeviation; 17 nMinDeviation = nDeviation < nMinDeviation ? nDeviation : nMinDeviation; 18 nSumDeviation += nDeviation; 19 dwLastTime = dwCurrentTime; 20 Sleep(50); 21 } 22 printf("nMaxDeviation = %2dms, nMinDeviation = %dms, nSumDeviation = %4dms, AverDeviation = %.3fms\n", 23 nMaxDeviation, nMinDeviation, nSumDeviation, nSumDeviation / 1000.0f); 24 25 return 0; 26 } View Code

比較GetTickCount、GetTickCountClock、GetTickCountCalibrate的精度如下:

GetTickCount           nMaxDeviation = 13ms, nMinDeviation = 3ms, nSumDeviation = 5079ms, AverDeviation = 5.079ms
GetTickCountClock      nMaxDeviation =  2ms, nMinDeviation = 0ms, nSumDeviation =    4ms, AverDeviation = 0.004ms
GetTickCountCalibrate  nMaxDeviation =  1ms, nMinDeviation = 0ms, nSumDeviation =    3ms, AverDeviation = 0.003ms

可以看到,原生的GetTickCount誤差過大,最大誤差13ms,平均誤差5ms,肯定無法滿足毫秒級的計時需求。

GetTickCountClock與GetTickCountCalibrate在精度上相差無幾,都可以滿足毫秒級的計時需求。

區別在於,GetTickCountClock是從當前程序運行開始計時,GetTickCountCalibrate是從系統啟動開始計時。

 

有關溢出

4個字節的ULONG最大值是4294967296ms,也就是49.7天,超過這個值就會溢出。


在excel中怎計算帶毫秒的時間差

1秒=1000毫秒,所以,你的2分54秒72毫秒其實就是2'54.072",這樣就可以計算了,你的結果是:2.993秒。

我明白你的意思了,你是因為表中數據無法計算是吧。
如果解決你這個問題有辦法是這樣的,比如,你2分54秒72在A1單元格,2分51秒79 在B1單元格,你現在要在C1中得到差:2.993秒。是不是這樣?

如果是你的操作應該是這樣的。先用分列操作把2分54秒72這樣的數據分成三列,分列操作進行兩次,分隔符為其他,寫上漢字分和秒,同樣操作對另一組數據,當這個數據中間沒有空列的時候,用插入的方式解決。這個操作完成後,A1為2,B1為54,C1為72,D1為2,E1為51,F1為79,然後你在G1上輸入公式進行減運算。比如:=A1-D1&"分"&(B1+C1/1000)-(E1+F1/1000)&"秒"
公式顯示的結果是:0分2.993秒
進行公式拖動填充。
希望你能看得明白。

如果你還需要表格恢復到以前的樣子,接下來的操作如下 。
復制G1列,在G列選擇性粘貼,數值,確定。在A1前和E1(兩個分鐘數前)各插入一列,在A1列中輸入公式:=B1&"分"&C1&"秒"&D1,
E1列中輸入公式:=F1&"分"&G1&"秒"&H1
分別拖動進行填充,然後復制選擇性粘貼數值,以去掉剛才編輯的公式,刪除表中是BCDFGH六列,這樣表格就恢復成原來的樣子了。
 

毫秒單位怎兩個計算時間差

日期相減計算出多少天。時間相減計算出秒。 毫秒相減再計算出毫秒。最後相加。
還有一種方法。把兩個時間都轉成數字形,再相減。
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved