使用 awk 處理時間的時區問題

gnu awk 有提供時間處理函數, 可以把解析並把時間字串轉成其它格式,像轉成 unix 秒做計算。 但 awk 預設是將時間依本機的時區解析, 如果要解析 utc 或其它時區, 那可以設定環境變數 TZ,設 TZ=utc 即可。

gnu awk 有提供 mktime 函數,可以解析常見的年月日格式。 雖然輸入格式蠻爛的,用空格分割的字串: %Y %m %d %H %M %S 。 awk 手冊裡寫 mktime 的回傳值是 timestamp, 但測試大概是整數,可以直接加減沒問題。 或者就用 strftime,格式指定 unix time %s , 雖然結果是字串,但 awk 是不區分字串和數字的。

但解析時會把時間套用本機的時區,然後再轉成 utc 時區的 unix time。 所以 2000 01 01 00 00 00 在台灣東 8 區解析, 以 unix time 表示是 946656000, 將此 unix time 表示為 utc 時間則會變成 1999 12 31 16 00 00

~ $ date -Is -d @946656000
2000-01-01T00:00:00+08:00
~ $ date --utc -Is -d @946656000 
1999-12-31T16:00:00+00:00

google 了怎麼解決,發現許多 gnu 程式都會吃 TZ 環境變數來決定時區。 (雖然 linux 下程式多半不會靠這個環境變數。) 該環境變數好像和 time.h 有關,可以參考手冊 tzname(3) 。 總之就是,設定 TZ=UTC 就可以讓時間是 utc。

TZ=UTC awk # some code
env TZ=UTC awk # use env

至於如果要處理時區偏移, awk 似乎沒有加減時區的功能,我是直接加減 n*3600