JavaScriptを有効にしてください

【Elixir】タイムゾーンエラーの解決策

 ·  ☕ 3 分で読めます

【Elixir】タイムゾーンエラーの解決策

Elixirで日付と時間を扱う際には、DateTimeモジュールが一般的に使用されます。
しかし、特定のタイムゾーンを指定して現在の日時を取得しようとすると、cannot get current datetime in "Japan" time zone, reason: :utc_only_time_zone_databaseというエラーが発生することがあります。
このエラーの原因と解決策について詳しく説明します。

エラーの原因

このエラーは、ElixirがデフォルトでUTCのみをサポートしているために発生します。
つまり、ElixirのDateTimeモジュールは、デフォルトではUTC以外のタイムゾーンを認識できません。したがって、特定のタイムゾーン(この場合は"Japan")を指定して現在の日時を取得しようとすると、上記のエラーが発生します。

解決策

この問題を解決するためには、タイムゾーンデータベースを提供するライブラリを導入する必要があります。
Elixirでは、この目的のためにtzdataというライブラリが提供されています。
tzdataはIETFのTime Zone Databaseを使用して、世界中のすべてのタイムゾーンの情報を提供します。
Tzdata

以下に、tzdataを導入してエラーを解決する手順を示します。

  1. まず、mix.exsファイルのdeps関数にtzdataを追加します。
1
2
3
4
5
defp deps do
  [
    {:tzdata, "~> 1.1"}
  ]
end
  1. 次に、config.exsファイルに以下の設定を追加します。
1
config :elixir, :time_zone_database, Tzdata.TimeZoneDatabase
  1. 最後に、プロジェクトの依存関係を更新します。
1
mix deps.get

これで、ElixirのDateTimeモジュールは"Japan"などのタイムゾーンを認識できるようになります。以下に、“Japan"タイムゾーンで現在の日時を取得する例を示します。

1
DateTime.now("Japan")

このコードを実行すると、日本の現在の日時がDateTime構造体として返されます。

タイムゾーン一覧

各地のタイムゾーンのリストは以下で出力が可能です。

1
iex> Tzdata.zone_list

また以下のようにするとタイムゾーンが検索できます。

1
2
3
4
iex> Tzdata.zone_list |> Enum.filter(& String.contains?(&1, "Japan"))
["Japan"]
iex> Tzdata.zone_list |> Enum.filter(& String.contains?(&1, "Asia/Tokyo"))
["Asia/Tokyo"]

まとめ

ElixirのDateTimeモジュールはデフォルトでUTCのみをサポートしているため、特定のタイムゾーンで現在の日時を取得しようとするとエラーが発生することがあります。しかし、tzdataというライブラリを導入することで、この問題を解決ができます。
tzdataはIETFのTime Zone Databaseを使用して、世界中のすべてのタイムゾーンの情報を提供します。
これにより、ElixirのDateTimeモジュールは任意のタイムゾーンを認識できるようになります。

Elixirで日付と時間を扱う際には、このようなエラーに遭遇することがありますが、適切なライブラリを導入することで解決することが可能です。
Elixirは柔軟性と拡張性が高い言語であるため、このような問題に対してもコミュニティが多くの解決策を提供しています。

この記事が、Elixirで日付と時間を扱う際のエラー解決の一助となれば幸いです。

共有

こぴぺたん
著者
こぴぺたん
Copy & Paste Engineer