當你在程式內想取得電腦現在的時間時,需要小心你取得的是本地時區的時間 (Localtime),還是世界協調時間 (UTC/GMT,雖然在科學的定義上UTC和GMT有少許不一樣,但一般在寫程式上會視兩者為同一物)。寫程式很容易犯的錯誤就是沒有考慮到底取得了哪個時區的時間。如果運行程式的電腦(尤其是伺服器)有機會是處於不同時區,而你想取得的是準確的時間(尤其是要計算或顯示時、分、秒),那就千萬別拿本地時區時間。
假設我們身處香港,時區是UTC+8,有一個伺服器程式會在每天香港時間晚上六點執行一次任務。如果這個程式在一部UTC(+0)的電腦上執行,就會變成香港時間凌晨兩點才執行。也許你會覺得只要能夠自行設定這個時間而不是寫死(hardcode)在程式內,再看看目標電腦是哪個時區而更改設定,就能解決這個問題。但一來我們有時候並不知道目標電腦的時區是甚麼,二來有一些程式邏輯可能假定了執行任務時的日期,當出現跨日期的情況就更難處理。
其實最簡單的方法就是永遠只取得世界協調時間,再將其調整成你自己想要的時區。例如在香港的話,取得世界協調時間後直接加上八小時。這樣無論電腦是設置成哪個時區,我們都能取得正確的香港時間。當然視乎情況也可以一律只使用UTC時間作準
C++程式碼例子:
c#程式碼例子:
- //Get UTC+8 Time (Windows MFC library)
- CTime ctNow = CTime::GetCurrentTime();
- tm tmHongKongTime;
- (ctNow + CTimeSpan(0, 8, 0, 0)).GetGmtTm(tmHongKongTime);
- return tmHKT;
- // Get UTC+8 Time (Standard library)
- time_t t = time(NULL);
- struct tm *tmHKT = gmtime(&t); //still GMT, not yet HKT
- tmHKT->tm_hour += 8; //add 8 to GMT
- mktime(tmHKT); //recompute the values to make it valid
- return tmHKT;
- // Print time
- printf("Now is %d/%d/%d %02d:%02d:%02d HKT",
- tmHKT->tm_year + 1900, tmHKT->tm_mon + 1, tmHKT->tm_mday,
- tmHKT->tm_hour, tmHKT->tm_min, tmHKT->tm_sec);
C#的DateTime可以直接在上面設定時區,然後無論是Property還是Print出來的時間都會自動幫你調成該時區的時間:
JavaScript程式碼例子:
- // Assume now is 2018:08:23 16:27:04 Hong Kong Time
- // UTC Time: 2018-08-23 08:27:04 Utc 8 636706096247972300
- DateTime dtUTC = DateTime.UtcNow;
- Console.WriteLine("{0} {1} {2} {3}", dtUTC, dtUTC.Kind, dtUTC.Hour, dtUTC.Ticks);
- // Local Time (now Hong Kong Time): 2018-08-23 16:27:04 Local 16 636706384247972300
- DateTime dtLocal = dtUTC.ToLocalTime();
- Console.WriteLine("{0} {1} {2} {3}", dtLocal, dtLocal.Kind, dtLocal.Hour, dtLocal.Ticks);
- // Absolute Hong Kong Time (ignore machine timezone): 2018-08-23 16:27:04 Unspecified 16 636706384247972300
- DateTime dtHKT = TimeZoneInfo.ConvertTimeFromUtc(dtUTC, TimeZoneInfo.FindSystemTimeZoneById("China Standard Time"));
- Console.WriteLine("{0} {1} {2} {3}", dtHKT, dtHKT.Kind, dtHKT.Hour, dtHKT.Ticks);
- //JavaScript
- function GetAbsoluteHKTime()
- {
- var now = new Date();
- now.setUTCHours(now.getUTCHours() + 8);
- return {
- "year" : now.getUTCFullYear(),
- "month" : now.getUTCMonth(),
- "date" : now.getUTCDate(),
- "hour" : now.getUTCHours(),
- "minute" : now.getUTCMinutes(),
- "second" : now.getUTCSeconds()
- };
- }
- var j = GetAbsoluteHKTime();
- console.log("Now is " + j.year + "/" + j.month + "/" + j.date + " "
- + ('0' + j.hour).slice(-2) + ":"
- + ('0' + j.minute).slice(-2) + ":"
- + ('0' + j.second).slice(-2) + " HKT");
- // Get UTC+8 Time (Windows MFC library)
- SYSTEMTIME st;
- GetSystemTime(&st);
- CTime ctHongKongTime = CTime(st) + CTimeSpan(0, 8, 0, 0)