上一篇中介紹了C運行庫中的時間處理函數。這一篇介紹Windows SDk中提供的時間函數。兩種時間系統之間沒有本質區別(事實上CRT時間是用Windows時間實現的,當然這是說的VC實現),同樣提供本地時間和UTC時間之間的轉換。不過CRT中的tm時間在SDK中對應為系統時間(SYSTEMTIME),CRT中的time_t時間在SDK中對應的為檔案時間(FILETIME),那個"特殊時刻"也變成1601年1月1日的子夜。
當然,首先要弄清楚FILETIME與SYSTEMTIME定義。
view plaincopy to clipboardprint?
- typedef struct _FILETIME {
- DWORD dwLowDateTime;
- DWORD dwHighDateTime;
- } FILETIME, *PFILETIME;
- typedef struct _SYSTEMTIME {
- WORD wYear;
- WORD wMonth;
- WORD wDayOfWeek;
- WORD wDay;
- WORD wHour;
- WORD wMinute;
- WORD wSecond;
- WORD wMilliseconds;
- } SYSTEMTIME, *PSYSTEMTIME;
typedef struct _FILETIME {<br /> DWORD dwLowDateTime;<br /> DWORD dwHighDateTime;<br />} FILETIME, *PFILETIME;<br />typedef struct _SYSTEMTIME {<br /> WORD wYear;<br /> WORD wMonth;<br /> WORD wDayOfWeek;<br /> WORD wDay;<br /> WORD wHour;<br /> WORD wMinute;<br /> WORD wSecond;<br /> WORD wMilliseconds;<br />} SYSTEMTIME, *PSYSTEMTIME;
比較一下,很明顯,FILETIME與time_t類似,是64位整型,不過FILETIME是以100納秒(ns)為單位。SYSTEMTIME與tm類似,不過多了一項wMilliseconds。可以看出,SDK時間比CRT的時間提供了更高的精度。同時SDK提供了更豐富的函數來處理時間。
view plaincopy to clipboardprint?
- void GetSystemTime(
- LPSYSTEMTIME lpSystemTime);
- void GetLocalTime(
- LPSYSTEMTIME lpSystemTime);
void GetSystemTime(<br /> LPSYSTEMTIME lpSystemTime);<br />void GetLocalTime(<br /> LPSYSTEMTIME lpSystemTime);<br />
這兩個函數獲得SYSTEMTIME形式的目前時間,不過GetSystemTime函數獲得當前的UTC時間,GetLocalTime獲得當前的本地時間,可以想象,獲得的兩個時間存在著時差。類似於CRT中提供tm與time_t之間的轉換,SDK也提供了兩個函數來轉換SYSTEMTIME時間與FILETIME時間。
view plaincopy to clipboardprint?
- BOOL SystemTimeToFileTime(
- const SYSTEMTIME* lpSystemTime,
- LPFILETIME lpFileTime);
- BOOL FileTimeToSystemTime(
- const FILETIME* lpFileTime,
- LPSYSTEMTIME lpSystemTime);
BOOL SystemTimeToFileTime(<br /> const SYSTEMTIME* lpSystemTime,<br /> LPFILETIME lpFileTime);<br />BOOL FileTimeToSystemTime(<br /> const FILETIME* lpFileTime,<br /> LPSYSTEMTIME lpSystemTime);<br />
函數命名很self-explanatory,就不用多說了吧。
SDK還提供了兩個很有趣的函數。
view plaincopy to clipboardprint?
- BOOL LocalFileTimeToFileTime(
- const FILETIME* lpLocalFileTime,
- LPFILETIME lpFileTime);
- BOOL FileTimeToLocalFileTime(
- const FILETIME* lpFileTime,
- LPFILETIME lpLocalFileTime);
BOOL LocalFileTimeToFileTime(<br /> const FILETIME* lpLocalFileTime,<br /> LPFILETIME lpFileTime);<br />BOOL FileTimeToLocalFileTime(<br /> const FILETIME* lpFileTime,<br /> LPFILETIME lpLocalFileTime);<br />
LocalFileTimeToFileTime函數將本地的FILETIME時間轉換為對應的UTC的FILETIME時間。我覺得,這個函數只是通過將本地時間減去與UTC時間的時間差來實現轉換,比如在東八區的本地時間轉換為對應的UTC時間,只需要將本地時間減去8*60*60*1000*1000*10(單位100ns)。類似,FileTimeToLocalFileTime函數是將UTC時間轉換為本地時間,它只是將減去時間差換成加上時間差。
瞭解了這些功能,讓我們用代碼說話吧。
view plaincopy to clipboardprint?
- #include <stdlib.h>
- #include <stdio.h>
- #include <time.h>
- #include <windows.h>
-
-
- int main()
- {
- SYSTEMTIME stLocal, stUTC, stUTC2;
- FILETIME ftLocal, ftUTC, ft;
- ULARGE_INTEGER uli;
-
- GetLocalTime(&stLocal);
- GetSystemTime(&stUTC);
- printf("Local System Time(YYYY-MM-DD HH:MM:SS): %d-%d-%d %d:%d:%d/n", stLocal.wYear, stLocal.wMonth,
- stLocal.wDay, stLocal.wHour, stLocal.wMinute, stLocal.wSecond);
- printf("UTC System Time (YYYY-MM-DD HH:MM:SS): %d-%d-%d %d:%d:%d/n", stUTC.wYear, stUTC.wMonth,
- stUTC.wDay, stUTC.wHour, stUTC.wMinute, stUTC.wSecond);
-
- SystemTimeToFileTime(&stLocal, &ftLocal);
- uli.LowPart = ftLocal.dwLowDateTime;
- uli.HighPart = ftLocal.dwHighDateTime;
- printf("Local File Time: %llu/n", uli.QuadPart);
-
- LocalFileTimeToFileTime(&ftLocal, &ftUTC);
- uli.LowPart = ftUTC.dwLowDateTime;
- uli.HighPart = ftUTC.dwHighDateTime;
- printf("UTC File Time: %llu/n", uli.QuadPart);
-
- FileTimeToSystemTime(&ftUTC, &stUTC2);
- printf("UTC System Time2 (YYYY-MM-DD HH:MM:SS): %d-%d-%d %d:%d:%d/n", stUTC2.wYear, stUTC2.wMonth,
- stUTC2.wDay, stUTC2.wHour, stUTC2.wMinute, stUTC2.wSecond);
-
- return EXIT_SUCCESS;
- }
#include <stdlib.h><br />#include <stdio.h><br />#include <time.h><br />#include <windows.h></p><p>int main()<br />{<br />SYSTEMTIMEstLocal, stUTC, stUTC2;<br />FILETIMEftLocal, ftUTC, ft;<br />ULARGE_INTEGERuli;</p><p>GetLocalTime(&stLocal);<br />GetSystemTime(&stUTC);<br />printf("Local System Time(YYYY-MM-DD HH:MM:SS): %d-%d-%d %d:%d:%d/n", stLocal.wYear, stLocal.wMonth,<br />stLocal.wDay, stLocal.wHour, stLocal.wMinute, stLocal.wSecond);<br />printf("UTC System Time (YYYY-MM-DD HH:MM:SS): %d-%d-%d %d:%d:%d/n", stUTC.wYear, stUTC.wMonth,<br />stUTC.wDay, stUTC.wHour, stUTC.wMinute, stUTC.wSecond);</p><p>SystemTimeToFileTime(&stLocal, &ftLocal);<br />uli.LowPart = ftLocal.dwLowDateTime;<br />uli.HighPart = ftLocal.dwHighDateTime;<br />printf("Local File Time: %llu/n", uli.QuadPart);</p><p>LocalFileTimeToFileTime(&ftLocal, &ftUTC);<br />uli.LowPart = ftUTC.dwLowDateTime;<br />uli.HighPart = ftUTC.dwHighDateTime;<br />printf("UTC File Time: %llu/n", uli.QuadPart);</p><p>FileTimeToSystemTime(&ftUTC, &stUTC2);<br />printf("UTC System Time2 (YYYY-MM-DD HH:MM:SS): %d-%d-%d %d:%d:%d/n", stUTC2.wYear, stUTC2.wMonth,<br />stUTC2.wDay, stUTC2.wHour, stUTC2.wMinute, stUTC2.wSecond);</p><p>return EXIT_SUCCESS;<br />}
程式輸出結果如下:
代碼13行GetLocalTime函數獲得當前的本地SYSTEMTIME時間,14行獲得對應的UTC的SYSTEMTIME時間,如輸出結果前兩行所顯示,兩者相差8小時(淩晨還在寫部落格,表揚下自己。。。)。
20行SystemTimeToFileTime函數將本地SYSTEMTIME時間轉換為方便計算的本地FILETIME形式時間,如輸出結果第三行所顯示。
25行LocalFileTimeToFileTime函數將本地FileTime時間轉換為對應的UTC的FILETIME時間,如輸出結果第四行所顯示。就像前面介紹的,如果你將輸出結果第三,四兩行所顯示的數字相減,併除以10*1000*1000*60*60,你將會得出8,你可以算下試試,記住FILETIME是以100納秒為單位的。
最後30行FileTimeToSystemTime將FILETIME時間轉換為SYSTEMTIME時間。可以看出輸出結果中第五行與第二行相同,這是必須的,因為兩者都是當前本地時間對應的UTC時間。