状況
JSTの現在時刻を取得しようとして、Timex.DateTime.local/0
を実行したところ、AmazonLinuxでは動作するのに手元のCentOSでは動作しない・・という事象が発生。このバグの調査過程でTimexのlocal timezoneの取得処理を調べたのでまとめる。
環境
Elixir 1.3.0
Timex 2.1.6
原因
TimexではTZ環境変数を再優先で利用するが、JST-9
の書式は利用できず、Asia/Tokyo
の形式しか利用できない。
今回の環境では、CentOS側にのみTZ=JST-9
が設定されていたのが原因だった。
概要
ドキュメントにある通り、Linuxでのtimezoneは以下の順に取得していき、取得できたらそれを利用する。
- TZ環境変数
- /etc/timezone
- /etc/sysconfig/clock
- /etc/conf.d/clock
- /etc/localtime
- /usr/local/etc/localtime
今回問題になったのがTZ環境変数にJST-9
と設定してあると、Timex上では Asia/Tokyo
の書式しか利用できないためにエラーになるということだった。
これは、Tzdataを利用して、timezoneを判定しているため。
呼び出しの流れは以下のとおり。
- Timex.DateTime.local/0
- Timex.Timezone.local/1
- Timex.Timezone.get/2
- Timex.Timezone.name_of/1
- Tzdata.zone_exists?/1
- Timex.Timezone.lookup_posix/1
Tzdata.zone_exists?/1
で、falseが返された後に Timex.Timezone.lookup_posix/1
で全てのTzdataからチェックをかけているが、JST-9
の書式は判定できないので、{:error, {:invalid_timezone, tz}}
が返される。
まとめ
日付処理は面倒な処理が多いのでTimexを多用するものの、ちょっとしたことで結構ハマる。なので、Timexあるあるがもっと増えると嬉しいと思った。
また、1.3で導入されたCalendar module
も試して、導入を検討していきたい。