線上的服務有世界各地的人來使用(若是有提供英文語系的話), 就有可能遇到需要幫世界各地的時區算時間.
要做個時區分佈設定(ex: 台灣是 +8), 想要選取後, 自動秀出他的時間, 照理說就是現在時間 -8hr 即可(設定於台灣機器而言), 但是又想到機器可能會換, 程式還是該寫好點才行, 於是花了點時間做研究.
本來想用 PHP 時間轉換 By 地區
這個來搞定, 要寫時才發現不曉得各時區的地區名稱等, 用這個反而累. XD
研究時找到兩個 PHP function, 先記著, 之後可以搭配著用:
- 列出全部區域的名稱 - timezone_abbreviations_list()
- 列出全部區域的名稱、日光節約時間(DST)多久、離 GMT 差多久. - listAbbreviations()
列出全部區域的名稱 - timezone_abbreviations_list()
- <?php
- $timezone_identifiers = DateTimeZone::listIdentifiers();
- print_r($timezone_identifiers);
- ?>
列出全部區域的名稱、日光節約時間(DST)多久、離 UTC 差多久. - listAbbreviations()
- <?php
- $timezone_abbreviations = DateTimeZone::listAbbreviations();
- print_r($timezone_abbreviations);
- ?>
藉由這次研究, 特別是 GMT / UTC 等時間, 靠下述兩篇 Wikipedia 的文章, 觀念也清楚不少.
名詞解釋
- UTC: Coordinated Universal Time 協調世界時是以原子時秒長為基礎,在時刻上盡量接近於世界時的一種時間計量系統。
- GMT: Greenwich Mean Time 格林威治標準時間,例如台北為 GMT + 8 就是台北的時區為格林威治標準時間 + 8 個小時。
- DST: Daylight Saving Time 就是指該地區正在施行日光節約的夏令時間,也就是當地標準時間 + 1 個小時。
於是, 要算當地時間的話, 需要先在取得機器的 UTC 時間, 再去換算成當地時間就可以了.
以台灣地區為例, 要取得 UTC 的時差:
- 測試: 執行 gmmktime(0, 0, 0, 1, 1, 1970) 得到 0, 再執行 mktime(0, 0, 0, 1, 1, 1970) 得到 -28800 = -8hr.
- 現在機器在台灣, 但是台灣的時區(Time zone)比 UTC 時間快 8小時, 所以上面 mktime(0, 0, 0, 1, 1, 1970); 會是 -8hr.
程式:
將相關的 PHP function 都拿來測試, 測取得 UTC 的方法, 有下述這幾類. (最下面那欄 UTC 是錯誤的)
- <?php
- echo "======================\n";
- echo 'UTC 1970: ' . gmmktime(0, 0, 0, 1, 1, 1970) . "\n"; // 0
- echo 'TW 1970: ' . mktime(0, 0, 0, 1, 1, 1970) . "\n"; // -28800secs = -8hr
- echo "======================\n";
- echo 'UTC Timestamp: ' . $t . "\n"; // 1236129510
- echo 'TW Timestamp: ' . time() . "\n"; // 1236158310
- echo "======================\n";
- // gmstrftime("%b %d %Y %H:%M:%S", mktime(date('H,i,s,n,j,Y')));
- echo 'UTC: ' . gmstrftime("%b %d %Y %H:%M:%S") . "\n"; // UTC: Mar 04 2009 09:08:47
- echo 'TW: ' . strftime("%b %d %Y %H:%M:%S") . "\n"; // TW: Mar 04 2009 17:08:47
- echo "======================\n";
- echo 'TW: ' . date('Y-m-d H:i:s') . "\n"; // TW: 2009-03-04 17:08:47
- echo "======================\n";
- echo "======================\n";
- ?>
由上述可得到, 要取得 UTC 的時間, 用此方法運算即可: time() + mktime(0, 0, 0, 1, 1, 1970);
於是寫兩個 Function 來做, 取得 UTC 時間 和 傳入地區時間, 算出當地時間(此 function 並未考慮 DST 的時間).
- <?php
- function get_utc_timestamp()
- {
- }
- function get_timestamp_from_timezone($tz_offset = 0)
- {
- if ($tz_offset > 14 || $tz_offset < -12)
- $tz_offset = 0; // timezone offset range: -12 ~ 14
- }
- /* Test */
- echo 'UTC: ' . date('Y-m-d H:i:s', get_timestamp_from_timezone()) . "\n";
- echo 'TW: ' . date('Y-m-d H:i:s', get_timestamp_from_timezone(8)) . "\n";
- echo '-8: ' . date('Y-m-d H:i:s', get_timestamp_from_timezone(-8)) . "\n";
- ?>
世界時間 測試對照
下述網站有時區對照, 可以知道世界各地目前時間, 再藉此跟上述程式去做些比對囉~ 🙂