C++ 獲取檔案時間問題
一、方法1
FileTime與Systime 的定義
1. typedef struct _FILETIME { 2. DWORD dwLowDateTime; 3. DWORD dwHighDateTime; 4. } FILETIME, *PFILETIME; 5. typedef struct _SYSTEMTIME { 6. WORD wYear; 7. WORD wMonth; 8. WORD wDayOfWeek; 9. WORD wDay; 10. WORD wHour; 11. WORD wMinute; 12. WORD wSecond; 13. WORD wMilliseconds; 14. } SYSTEMTIME, *PSYSTEMTIME;
比較一下,很明顯,FILETIME與time_t類似,是64位整型,不過FILETIME是以100納秒(ns)為單位。SYSTEMTIME與tm類似,不過多了一項wMilliseconds。可以看出,SDK時間比CRT的時間提供了更高的精度。同時SDK提供了更豐富的函式來處理時間。
這兩個函式獲得SYSTEMTIME形式的當前時間,不過GetSystemTime函式獲得當前的UTC時間,GetLocalTime獲得當前的本地時間,可以想象,獲得的兩個時間存在著時差。類似於CRT中提供tm與time_t之間的轉換,SDK也提供了兩個函式來轉換SYSTEMTIME時間與FILETIME時間。
1. BOOL SystemTimeToFileTime( 2. const SYSTEMTIME* lpSystemTime, 3. LPFILETIME lpFileTime); 4. BOOL FileTimeToSystemTime( 5. const FILETIME* lpFileTime, 6. LPSYSTEMTIME lpSystemTime);
SDK還提供了兩個很有趣的函式。
1. BOOL LocalFileTimeToFileTime(
2. const FILETIME* lpLocalFileTime,
3. LPFILETIME lpFileTime);
4. BOOL FileTimeToLocalFileTime(
5. const FILETIME* lpFileTime,
6. LPFILETIME lpLocalFileTime);
LocalFileTimeToFileTime函式將本地的FILETIME時間轉換為對應的UTC的FILETIME時間。我覺得,這個函式只是通過將本地時間減去與UTC時間的時間差來實現轉換,比如在東八區的本地時間轉換為對應的UTC時間,只需要將本地時間減去8*60*60*1000*1000*10(單位100ns)。類似,FileTimeToLocalFileTime函式是將UTC時間轉換為本地時間,它只是將減去時間差換成加上時間差。
1. SYSTEMTIME stLocal, stUTC, stUTC2;
2. FILETIME ftLocal, ftUTC, ft;
3. ULARGE_INTEGER uli;
4.
5. GetLocalTime(&stLocal);
6. GetSystemTime(&stUTC);
7. printf("Local System Time(YYYY-MM-DD HH:MM:SS): %d-%d-%d %d:%d:%d/n", stLocal.wYear, stLocal.wMonth,
8. stLocal.wDay, stLocal.wHour, stLocal.wMinute, stLocal.wSecond);
9. printf("UTC System Time (YYYY-MM-DD HH:MM:SS): %d-%d-%d %d:%d:%d/n", stUTC.wYear, stUTC.wMonth,
10. stUTC.wDay, stUTC.wHour, stUTC.wMinute, stUTC.wSecond);
11.
12. SystemTimeToFileTime(&stLocal, &ftLocal);
13. uli.LowPart = ftLocal.dwLowDateTime;
14. uli.HighPart = ftLocal.dwHighDateTime;
15. printf("Local File Time: %llu/n", uli.QuadPart);
16.
17. LocalFileTimeToFileTime(&ftLocal, &ftUTC);
18. uli.LowPart = ftUTC.dwLowDateTime;
19. uli.HighPart = ftUTC.dwHighDateTime;
20. printf("UTC File Time: %llu/n", uli.QuadPart);
21.
22. FileTimeToSystemTime(&ftUTC, &stUTC2);
23. printf("UTC System Time2 (YYYY-MM-DD HH:MM:SS): %d-%d-%d %d:%d:%d/n", stUTC2.wYear, stUTC2.wMonth,
24. stUTC2.wDay, stUTC2.wHour, stUTC2.wMinute, stUTC2.wSecond);
利用GetFileTime()函式獲取檔案時間
Handle hFile;
int iRet = hFile.Open(strPath.c_str(), CFile::modeRead);
FILETIME fCreateTime, fAccessTime, fWriteTime;
iRet = GetFileTime(hhFile.m_hFile, &fCreateTime, &fAccessTime, &fWriteTime);
1、但是這種獲取的時間需要用FileTimeToSystemTime()進行轉換。而且必須是轉換為SYSTEMTIME 型別時間否則轉換其他如CTime 則會導致時間變成一個無法想象的時間值
SYSTEMTIME sysTime;
ZeroMemory(&sysTime, sizeof(SYSTEMTIME));
FileTimeToSystemTime(&fCreateTime, &sysTime);
2、通過這種轉換的時間也會存在另外一個問題,SYSTEMTIME 用的是格林尼治時間,而中國用的是東八區時間,轉換後的時間會比原來時間少8個小時,因此需要在轉換為系統時間之前進一步轉換,轉換為本地檔案時間
FILETIME temp;
FileTimeToLocalFileTime(&fCreateTime ,&temp );
SYSTEMTIME sysTime;
ZeroMemory(&sysTime, sizeof(SYSTEMTIME));
FileTimeToSystemTime(&temp, &sysTime);
二、方法二
BOOL GetStatus(
CFileStatus& rStatus
) const;
static BOOL PASCAL GetStatus(
LPCTSTR lpszFileName,
CFileStatus& rStatus
);
1、CTime m_ctime The date and time the file was created. (檔案建立時間)
2、CTime m_mtime The date and time the file was last modified.
3、CTime m_atime The date and time the file was last accessed for reading.
4、ULONGLONG m_size The logical size of the file in bytes, as reported by the DIR command. 邏輯大小
5、BYTE m_attribute The attribute byte of the file. 屬性子節
6、char m_szFullName[_MAX_PATH] The absolute filename in the Windows character set. 檔名全稱
CFileStatus fileStatus;
CFile::GetStatus(strPath.c_str(), fileStatus);
tsRecvDate = Format(_T("%d%02d%02d"),fileStatus.m_ctime.GetYear(), fileStatus.m_ctime.GetMonth(), fileStatus.m_ctime.GetDay());
三、方法三
TCHAR DirSpec[MAX];
WIN32_FIND_DATA FindFileData;
hFind=FindFirstFile(DirSpec,&FindFileData);
FindFileData.ftLastWriteTime 是一種FILETIME 型別的時間 可以通過方法一進行轉換後得到所需要的時間;