VC中多種方式獲取世界基準時間
這裡介紹獲取世界當前時間(世界基準時間),這裡儘量採用多種方式,供大家選擇。不過首先要介紹世界時間的概念。
一、世界時間簡介
1、早期的世界時間
早期的世界時間是格林尼治標準時間(Greenwich Mean Time,GMT),它是指位於倫敦郊區的皇家格林尼治天文臺的標準時間,因為本初子午線被定義在通過那裡的經線。 理論上來說,格林尼治標準時間的正午是指當太陽橫穿格林尼治子午線時的時間。由於地球在它的橢圓軌道里的運動速度不均勻,這個時刻可能和實際的太陽時相差16分鐘。 地球每天的自轉是有些不規則的,而且正在緩慢減速。所以,格林尼治時間已經不再被作為標準時間使用。
2、當今的世界時間
當今的世界時間是協調世界時(UTC),由於它採用原子鐘計時,所以它的精確度很高。1972 年1 月1日,協調世界時(UTC)成為新的世界標準時間。故協調世界時已經替代格林尼治標準時間,成為當今的世界基準時間。
3、格林尼治標準時間仍然在起作用
由於格林尼治標準時間影響深遠,它仍然在起作用。Windows中,GMT和UTC沒有區別,被統稱為系統時間(System Time);在不需要精確到秒的情況下,通常也將GMT 和UTC 視作等同。
4、世界當前時間與北京時間的差距
北京時間位於東八區,則它比世界當前時間大8小時。因此,北京當前時間減去8小時,就等於世界當前時間,反之,世界當前時間加上8小時,就等於北京當前時間。
二、多種方式獲取世界當前時間
1、利用API函式獲取世界當前時間
獲取當前世界時間的API函式是GetSystemTime(),它的宣告如下:
void WINAPI GetSystemTime(
__out LPSYSTEMTIME lpSystemTime
);
引數:
lpSystemTime
指向SYSTEMTIME結構體的指標,用於接收當前本地日期和時間。
SYSTEMTIME結構體的宣告如下:
typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME;
成員介紹
wYear
年,有效範圍是1601到30827。
wMonth
月,有效範圍是1到12,分別對應1-12月。
wDayOfWeek
表示一週中的一天,即平常我們所說的星期幾,該成員可以是下列值之一:
0為星期天
1為星期一
2為星期二
3為星期三
4為星期四
5為星期五
6為星期六
wDay
日,這個成員的有效範圍是1到31。
wHour
時, 這個成員的有效範圍是0到23。
wMinute
分,這個成員的有效範圍是0到59。
wSecond
秒,這個成員的有效範圍是0到59。
wMilliseconds
毫秒,這個成員的有效範圍是0到999。
2、C語言執行庫函式獲取世界當前時間
gmtime()等
將時間值轉換為世界時區的正確值。
struct tm *gmtime(const time_t *timer);
struct tm *_gmtime32(const time32_t *timer);
struct tm *_gmtime64(const __time64_t *timer);
_gmtime64使用__time64_t結構,允許表示日期到UTC時間23:59:59,December 31, 3000, UTC;而_gmtime32只表示日期到UTC時間2038年1月19日03:14:07。 1970年1月1日午夜是這兩個函式的日期範圍的下限。
引數:
timer
time_t為老的32位時間,一個長整數,代表時間值。
time_t 與__time32_t等效。
__time64_t為__int64型別的整數,代表時間值。
返回值:
返回值為tm結構體型別,它的成員如下:
tm_sec
秒,有效範圍是0 - 59。
tm_min
分,有效範圍是0 - 59。
tm_hour
時,有效範圍是0 - 23。
tm_mday
日,有效範圍是1 - 31。
tm_mon
月,有效範圍是0 – 11,一月為0,二月為1……
tm_year
年,當前年份減去1900年。
tm_wday
星期幾,有效範圍是0 – 6,星期天月為0,星期一為1……
tm_yday
一年中的哪一天,有效範圍是0 – 365,一月1日為0,一月2日為1……
tm_isdst
正值,如果夏令時有效; 如果夏令時不生效,則為0;;如果夏時制的狀態未知,則為負值。 如果設定了TZ環境變數,那麼C執行時庫將假定適用於美國的規則來實現計算夏令時。
(2)、time()等
獲取系統時間。
time_t time(time_t *timer);
__time32_t _time32(__time32_t *timer);
__time64_t _time64(__time64_t *timer);
引數:
timer
指向時間儲存位置的指標。
返回值:
返回從1970年1月1日午夜開始經過的秒數,或者在發生錯誤的情況下返回-1。
3、MFC CTime類獲取世界當前時間
(1)、GetAsSystemTime ()
返回一個表示系統時間。
bool GetAsSystemTime(
SYSTEMTIME& st
) const throw( );
引數:
St
對SYSTEMTIME結構體的引用,該結構將儲存轉換後的CTime物件的日期/時間值。
SYSTEMTIME結構體的用法,參考GetSystemTime()部分。
返回值:
如果成功返回TRUE,否則返回FALSE。
(2)、GetGmtTm ()
獲取一個struct tm表本地時間,該struct tm包含此CTime物件中包含的時間的分解。
struct tm* GetGmtTm(struct tm* ptm) const;
引數:
ptm
輸出,指向將接收時間資料的緩衝區。 如果該指標為NULL,則丟擲異常。
結構體tm的用法,參考localtime()函式部分。
返回值:
一個指向包含檔案TIME.H中定義的已填充struct tm的指標。
注意1:GetGmtTm()不能直接獲取世界時間,但是它可以將本地當前時間轉換為世界時間。
注意2:GetAsSystemTime()函式名含“SystemTime”,但它不是用來獲取世界本地時間的。
本例的關鍵程式碼如下:
//1、利用API函式獲取世界當前時間
void CTestDlg::OnBnClickedButton1()
{
SYSTEMTIME st;
GetSystemTime(&st);
CString strRes;
strRes.Format("年:%d\n月:%d\n日:%d\n時:%d\n分:%d\n秒:%d\n毫秒:%d\n星期:%d",
st.wYear,
st.wMonth,
st.wDay,
st.wHour,
st.wMinute,
st.wSecond,
st.wMilliseconds,
st.wDayOfWeek);
MessageBox(strRes);
}
//2、C語言執行庫函式獲取世界當前時間
void CTestDlg::OnBnClickedButton2()
{
time_t timep;
struct tm *pTm;
time(&timep);
pTm = gmtime(&timep);
CString strRes1;
strRes1.Format("%d年%d月%d日-%d時:%d分:%d秒",
pTm->tm_year+1900,
pTm->tm_mon+1,
pTm->tm_mday,
pTm->tm_hour,
pTm->tm_min,
pTm->tm_sec);
MessageBox(strRes1); //結果為2021年12月11日-8時:25分:53秒
struct tm *newtime;
__int64 ltime;
char buff[80];
_time64(<ime); //以64位整數形式獲取時間。
newtime = _gmtime64(<ime);
asctime_s(buff, sizeof(buff), newtime);
CString strRes2;
strRes2.Format("%s",buff);
MessageBox(strRes2);
//結果為sat Dec 11 08:25:53 2021,即為2021年12月11日8時25分53秒
}
//3、MFC CTime類獲取世界當前時間
void CTestDlg::OnBnClickedButton3()
{
CTime time1(CTime::GetCurrentTime());
tm rtm;
time1.GetGmtTm(&rtm);
CString strRes1;
strRes1.Format("%d年%d月%d日-%d時:%d分:%d秒",
rtm.tm_year+1900,
rtm.tm_mon+1,
rtm.tm_mday,
rtm.tm_hour,
rtm.tm_min,
rtm.tm_sec);
MessageBox(strRes1);
CTime time2(CTime::GetCurrentTime());
SYSTEMTIME st;
time2.GetAsSystemTime(st);
CString strRes2;
strRes2.Format("年:%d\n月:%d\n日:%d\n時:%d\n分:%d\n秒:%d\n毫秒:%d\n星期:%d",
st.wYear,
st.wMonth,
st.wDay,
st.wHour,
st.wMinute,
st.wSecond,
st.wMilliseconds,
st.wDayOfWeek);
MessageBox(strRes2);
}