當你在程式內想取得電腦現在的時間時,需要小心你取得的是本地時區的時間 (Localtime),還是世界協調時間 (UTC/GMT,雖然在科學的定義上UTC和GMT有少許不一樣,但一般在寫程式上會視兩者為同一物)。寫程式很容易犯的錯誤就是沒有考慮到底取得了哪個時區的時間。如果運行程式的電腦(尤其是伺服器)有機會是處於不同時區,而你想取得的是準確的時間(尤其是要計算或顯示時、分、秒),那就千萬別拿本地時區時間。
假設我們身處香港,時區是UTC+8,有一個伺服器程式會在每天香港時間晚上六點執行一次任務。如果這個程式在一部UTC(+0)的電腦上執行,就會變成香港時間凌晨兩點才執行。也許你會覺得只要能夠自行設定這個時間而不是寫死(hardcode)在程式內,再看看目標電腦是哪個時區而更改設定,就能解決這個問題。但一來我們有時候並不知道目標電腦的時區是甚麼,二來有一些程式邏輯可能假定了執行任務時的日期,當出現跨日期的情況就更難處理。
其實最簡單的方法就是永遠只取得世界協調時間,再將其調整成你自己想要的時區。例如在香港的話,取得世界協調時間後直接加上八小時。這樣無論電腦是設置成哪個時區,我們都能取得正確的香港時間。當然視乎情況也可以一律只使用UTC時間作準
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#程式碼例子:
C#的DateTime可以直接在上面設定時區,然後無論是Property還是Print出來的時間都會自動幫你調成該時區的時間:
// 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程式碼例子:
//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)