如何使用pytz做時區轉換-以GPX為例

小鬼瀑布-小錐麓-大鬼瀑布
瑞芳小錐麓-大鬼瀑布
整理登山行程的blog時,為了讓看文章的人能夠瞭解行程中重要的地點需要花費的時間,寫了一個python小程式將所記錄的GPX軌跡檔內航點(Waypoint)、及記錄的時間點整理出來,這樣就可以知道點和點之間需要花費的時間。下面則是造訪瑞芳小錐麓-小鬼瀑布的範例…

南新宮(07:03) > 新路登山口(07:06) > 水泥橋(07:12) > 古厝遺址(07:21) > 俯瞰南雅社區(07:25) > 南子吝山叉(07:32) > 石梯坑岔(07:39) > 保羅尖岔(07:52) > 半屏溪(07:55) > 眺望大鬼瀑布(08:40) > 劍龍稜岔(08:57) > 小鬼瀑布岔(09:41) > 溪谷(09:52) > 小鬼瀑布(10:03) > 景觀台(12:57) > 景觀台岔(13:00) > 接回南子吝山步道(13:09) > 南子吝山(13:10) > 涼亭(13:33) > 南子吝山登山口(13:45),路線約6.3公里

因為GPX檔案內的時間都是UTC格式,而台灣地區為UTC+8 ,因此記錄的時間和台灣的時間會有八個小時的時間差。(關於UTC,可參考到底是 GMT+8 還是 UTC+8 ? - PanSci 泛科學

之前偷懶用了一個很簡單的解法,將小時直接加8來處理。沒想到……因為這次去瑞芳小錐麓時怕在山上塞人早早出門,不到七點就到南雅,所以使用oruxmaps所第一個記錄的航點(Waypoint)資料如下
<wpt lat="25.1206354" lon="121.8881537">
<ele>-4.03</ele>
<time>2018-06-08T23:03:32Z</time>
<name>&lt;![CDATA[南新宮]]&gt;</name>
<sym>Waypoint</sym>
<type>方位點</type>
<extensions>
<om:oruxmapsextensions xmlns:om="http://www.oruxmaps.com/oruxmapsextensions/1/0">
<om:ext subtype="0" type="ICON">1</om:ext>
</om:oruxmapsextensions>
</extensions>
</wpt>
可知紀錄的時間時間是前一天。當我採用直接加8時,程式就會有錯誤……於是,研究了一下正規的作法…

以下,則是列出原本直接加8(錯誤作法)、和使用pytz - World Timezone Definitions for Python的正確解法
#原始的偷懶錯誤作法,這樣會有超過24:00的問題
#pointlist = [[x.name, x.time.replace(hour=x.time.hour + 8).strftime("%H:%M")] for x in gpx.waypoints]

#使用pytz的作法
#先設定台灣所在時區
timezone = pytz.timezone('Asia/Taipei')
#加上時差
pointlist = [[x.name, (x.time+timezone.utcoffset(x.time)).strftime("%H:%M")] for x in gpx.waypoints]
註:我是使用gpxpy -- GPX file parser讀取GPX



參考資料

留言