VC++時間函數總結


1基本概念    1

1.1 基本概念    1

1.2 時間表示法    2

2 Win32 API    3

2.1 獲取    3

2.1.1 時間間隔    3

2.1.2 時刻    3

2.1.3 時區    3

2.1.4 時區信息    5

2.2 設置    6

2.2.1 時刻    6

2.2.2 時區    7

2.2.3 時間基准    7

2.3 比較    7

2.4 轉換    7

2.4.1 DOS時間與FILETIME轉換    8

2.4.2 SYSTEMTIMEFILETIME轉換    8

2.4.3 本地時間與UTC時間轉換    8

3 C運行時庫函數    9

3.1 獲取    9

3.1.1 時間間隔    9

3.1.2 時刻    9

3.2 設置    10

3.2.1 時刻    10

3.2.2 時區    10

3.3 比較    10

3.4 轉換    11

3.4.1 time_tstruct tm    11

3.5 格式化    12

3.5.1 asctime    12

3.5.2 ctime    12

3.5.3 strftime    12

4 MFC    13

 

1基本概念

1.1 基本概念

GMTGreenwich Mean Time)是格林尼治標准時間。它是通過觀測太陽來確定時間的,即力學時。力學時的精確度不是很高,所以它被協調世界時(Coordinate Universal Time,簡稱UTC)所取代。UTC采用原子鍾計時,所以它的精確度很高。Windows中,GMTUTC沒有區別,被統稱為系統時間(System Time)。

標准時(Standard Time)等於UTC時間加上時差,如:中國的時區為+8:00,北京時間就是UTC時間加上8小時。

某些國家在夏季還將執行夏令時,也就是日光節能時(Daylight Saving Time,簡稱DST)。就是在夏季將時鍾撥快1小時,早起早睡充分利用太陽光以達到節約能源的目的。UTC時間、標准時、夏令時的關系請參考下面兩張圖形:

圖1.1 北半球一年內的時間

圖1.2 南半球一年內的時間

Windows中,標准時和夏令時被統稱為本地時間(Local Time)。本地時間有時會有歧義,如圖1.1和圖1.2中的綠色部分,它所表示的本地時間是標准時還是夏令時?

1.2 時間表示法

VC中對時間的表示一般有兩種方法。一種是人們熟知的年、月、日、時、分、秒,如:SYSTEMTIMEstruct tm,這種表示方法被稱之為broken-down time

另一種是從基准時刻到當前時刻的時間間隔,如:time_t表示197011日到當前時刻的秒數,稱這種表示方法為calendar time。類似的還有FILETIME,它其實就是一個__int64,表示160111日到當前時刻的時間間隔(單位10-7 秒,即100納秒,萬分之一毫秒)。

 

2 Win32 API

2.1 獲取

2.1.1 時間間隔

GetTickCountGetTickCount64返回啟動Windows后到現在的毫秒數。GetTickCount返回一個DWORD,最大為0xFFFFFFFF秒,約為49.71天。也就是說連續運行Windows系統 50 天后,GetTickCount會從零開始計時。

GetTickCount64返回一個unsigned __int64,最大為0xFFFFFFFFFFFFFFFF秒,約為 5.8億年。再也不用擔心計時重新歸零的問題了。

2.1.2 時刻

GetSystemTime用於獲取毫秒級UTC時刻。

GetSystemTimeAsFileTime用於獲取10-7 秒級的UTC時刻。

GetLocalTime用於獲取本地時刻。要想知道這個時刻為標准時還是夏令時請通過GetTimeZoneInformation的返回值進行判斷:返回TIME_ZONE_ID_DAYLIGHT表示夏令時,返回TIME_ZONE_ID_STANDARDTIME_ZONE_ID_UNKNOWN表示標准時。TIME_ZONE_ID_UNKNOWN還表明了系統未啟用夏令時。

GetFileTime用於獲取打開文件(或文件夾)的UTC時刻。為了獲取未打開文件的UTC時刻,請使用FindFirstFile函數。

2.1.3 時區

GetTimeZoneInformation函數可以獲取時區信息,包括:時差、標准時偏差、夏令時偏差、夏令時開始時刻(標准時)、夏令時結束時刻(夏令時)。它獲取的時區信息保存在結構TIME_ZONE_INFORMATION內:

typedef struct _TIME_ZONE_INFORMATION { // tzi

LONG                Bias;

WCHAR            StandardName[32];

SYSTEMTIME        StandardDate;

LONG                StandardBias;

WCHAR            DaylightName[32];

SYSTEMTIME        DaylightDate;

LONG                DaylightBias;

} TIME_ZONE_INFORMATION;

這個結構各個成員變量的含義請參考下圖:

圖2.1 時區信息

Bias是時區時差的相反數,StandardBias為標准時偏差(沒發現不為零的情況),DaylightBias為夏令時偏差(一般為-60),它們的單位都是分鍾。UTC與標准時、夏令時的轉換公式如下:

UTC=標准時 + Bias + StandardBias

UTC=夏令時 + Bias + DaylightBias

DaylightDate是夏令時的開始時刻,它是標准時。DaylightDate 各個成員變量的含義如下:

成員變量

示例數值

wYear; 

年,一般為零

0 

wMonth; 

月。0表示沒有夏令時

4 

wDayOfWeek; 

06分別表示星期日至星期六

1 

wDay; 

第幾個,范圍[1,5]5表示最后一個。

0 

wHour; 

2 

wMinute; 

0 

wSecond; 

0 

wMilliseconds; 

毫秒

0 

以上表為例,夏令時的開始時刻為每年4月的第1個星期日的2:00:00.000

StandardDate是夏令時的結束時刻,它是夏令時。StandardDate各個成員變量的含義請參考上表。

注意:對於北半球而言,DaylightDate小於StandardDate,但是到了南半球則正好相反。

因為夏令時的開始、結束時間可能是變化的,自Vista后引入了下面兩個函數:

GetTimeZoneInformationForYear

GetDynamicTimeZoneInformation

2.1.4 時區信息

時區信息全部存放在注冊表里:

對於Windows 98而言,存放在如下位置:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Time Zones

對於Windows NT而言,存放在如下位置:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones

對於Windows CE而言,存放在如下位置:

HKEY_LOCAL_MACHINE\Time Zones

如:修改WinCE時區為北京時間:

[HKEY_LOCAL_MACHINE\Time Zones]
"Default"="China Standard Time"

注冊表里的二進制數據TZI,其結構如下:

#pragma pack(push,1)

class TZI

{

LONG        Bias;        //時差,單位:分鍾

LONG        StandardBias;    //標准時差,單位:分鍾

LONG        DaylightBias;    //夏令時時差,單位:分鍾

SYSTEMTIME    StandardDate;    //夏令時結束時刻

SYSTEMTIME    DaylightDate;    //夏令時開始時刻

};

#pragma pack(pop)

2.2 設置

2.2.1 時刻

SetSystemTime用於設置WindowsUTC時刻。

SetLocalTime用於設置Windows的本地時刻。如果Windows啟用了夏令時,有時會出現意想不到地后果。舉例說明:假定系統時區為-8:00,並啟用了夏令時。現在調用代碼 SetLocalTime(2000.07.07 10:11:12),將會有兩種不同的結果:

如果當前系統正處於夏令時,首先把2000.07.07 10:11:12轉換為UTC時刻,即2000.07.07 10:11:12+7:00=2000.07.07 17:11:12,然后調用SetSystemTime(2000.07.07 17:11:12)。因為2000.07.07 17:11:12處於夏令時,所以最終的本地時刻為2000.07.07 17:11:127:00=2000.07.07 10:11:12,這是一個令人滿意的結果。

如果當前系統處於標准時,首先把2000.07.07 10:11:12轉換為UTC時刻,即2000.07.07 10:11:12+8:00=2000.07.07 18:11:12,然后調用SetSystemTime(2000.07.07 18:11:12)。因為2000.07.07 18:11:12處於夏令時,所以最終的本地時刻為2000.07.07 18:11:127:00=2000.07.07 11:11:12,這個結果實在令人不可思議!

SetFileTime用於修改某個打開文件(或文件夾)的UTC時刻。不打開文件,如何修改其時刻?

2.2.2 時區

SetTimeZoneInformation

SetDynamicTimeZoneInformation

2.2.3 時間基准

將計算機的BIOS時間當作本地時間

REGEDIT4

 

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation]

"RealTimeIsUniversal"=dword:00000000

將計算機的BIOS時間當作UTC時間

REGEDIT4

 

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation]

"RealTimeIsUniversal"=dword:00000001

2.3 比較

CompareFileTime

2.4 轉換

2.4.1 DOS時間與FILETIME轉換

DosDateTimeToFileTime

FileTimeToDosDateTime

2.4.2 SYSTEMTIMEFILETIME轉換

FileTimeToSystemTime

SystemTimeToFileTime

2.4.3 本地時間與UTC時間轉換

FileTimeToLocalFileTime

LocalFileTimeToFileTime

如果Windows啟用了夏令時,上面兩個函數是無法正常工作的。如假定系統時區為-8:00,並啟用了夏令時。則將UTC時刻轉換為本地時刻將用到如下兩個公式:

夏令時=UTC7:00

標准時=UTC8:00

正確的做法是:首先根據UTC時刻判斷本地時刻是夏令時還是標准時,然后選擇公式進行計算。但上面兩個函數不是這么工作的,它們根據Windows當前處於夏令時還是標准時選擇公式進行計算。

SystemTimeToTzSpecificLocalTime

TzSpecificLocalTimeToSystemTime

 

3 C運行時庫函數

3.1 獲取

3.1.1 時間間隔

3.1.1.1 clock

原型:clock_t clock( void )

功能:返回進程已經運行的時間,單位:1 / CLOCKS_PER_SEC 秒。

注意:clock_t其實就是long

3.1.2 時刻

3.1.2.1 time, _time32, _time64

原型:time_t time( time_t *timer );

功能:返回當前UTC時刻。

說明:

1、返回值表示自 1970 1 1 日到當前時刻的秒數;

2、在VC++6.0中,沒有_time32, _time64time_t相當於long。因此,time_t最多只能表示到 2038-01-19 03:14:07

3、在VC++2005中,_time32的返回值為long_time64的返回值為__int64。至於time的返回值則要取決於是否定義了宏_USE_32BIT_TIME_T,定義了就是long,未定義就是__int64

3.1.2.2 _ftime

原型:void _ftime( struct _timeb *timeptr );

功能:獲得當前UTC時刻、時差、是否為夏令時等信息。

說明:

1、與time函數相比,_ftime獲得的時間精度更高(包含毫秒),信息更加豐富,如:包含時差信息。具體的請參考_timeb結構:

struct _timeb

{

time_t time;            //UTC時刻

unsigned short millitm;    //毫秒

short timezone;         //時差= UTC時刻 -本地時刻,單位:分鍾

short dstflag;            //非零表示目前正處於夏令時

};

3.1.2.3 _stat_fstat

用於獲取文件時間

3.1.2.4 _strdate

獲取當前UTC日期至一個字符串內

3.1.2.5 _strtime

獲取當前UTC時間至一個字符串內

3.2 設置

3.2.1 時刻

_utime_futime用於修改文件的訪問、修改時刻,它們的不同之處在於指定文件的方式不同:前者通過路徑名指定文件,后者通過文件句柄指定文件。

3.2.2 時區

請使用 _tzset 函數

3.3 比較

請使用 difftime 函數

3.4 轉換

3.4.1 time_tstruct tm

struct tm 結構如下:

struct tm

{

int tm_sec;    //[0,59]

int tm_min;    //[0,59]

int tm_hour;    //[0,23]

int tm_mday;    //[1,31]

int tm_mon;    //月減去一[0,11]

int tm_year;    //年減去1900

int tm_wday;    //星期[0,6]0表示周日

int tm_yday;    //年積日[0,365]

int tm_isdst;    //正數表示為夏令時,0表示標准時,小於零表示未知

};

它既可以表示UTC時刻,也可以表示本地時刻。表示本地時刻時,通過tm_isdst可以明確指定該時刻為標准時刻還是夏令時刻。

3.4.1.1 time_tUTC時刻)轉換為 struct tmUTC時刻)

請使用 gmtime 函數

3.4.1.2 struct tmUTC時刻)轉換為 time_tUTC時刻)

請使用 _mkgmtime 函數

3.4.1.3 time_tUTC時刻)轉換為 struct tm(本地時刻)

請使用 localtime 函數

3.4.1.4 struct tm(本地時刻)轉換為 time_tUTC時刻)

請使用 mktime 函數

原型:time_t mktime( struct tm *timeptr );

說明:

1timeptr-> tm_isdst為正數(一般為1)時,表示將夏令時轉換為UTC時刻;

2timeptr-> tm_isdst為零時,表示將標准時轉換為UTC時刻;

3timeptr-> tm_isdst為負數(一般為-1)時,函數將自動判斷本地時刻是夏令時還是標准時,然后再轉換為UTC時刻。注意:夏令時、標准時的判斷並不能完全正確;

3.5 格式化

3.5.1 asctime

struct tm轉換為字符串格式的時間

3.5.2 ctime

time_t轉換為字符串格式的時間

3.5.3 strftime

struct tm格式化輸出為字符串

 

4 MFC

MFC中,CTimeCOleDateTime可用於處理時間。它們的異同:

1CTime封裝的是C函數,COleDateTime封裝的是Win32 API

2CTime可以處理夏令時,COleDateTime沒有此功能;

3CTime以一個整數表示時刻,COleDateTime以一個double表示時刻。它們都只能精確到秒。

4VC++6.0CTime使用long表示時刻,時間范圍為 197011日至2038118日。自VC++2002以后,CTime使用__int64表示時刻,時間范圍為197011 12:00:0030001231日。

COleDateTime 表示的時間范圍:10011日至99991231日。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM