6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ElixirAdvent Calendar 2024

Day 10

Nervesでローカルタイムとタイムゾーン管理: NervesTimeZones の活用法

Posted at

はじめに

IoT デバイスや組み込みシステムでタイムゾーンやローカルタイムを管理することは、意外と難しい課題です。
本記事では、NervesTimeZones ライブラリを使ってこの課題を解決する方法をご紹介します。

Screen Shot 2021-12-21 at 12.12.38 PM.png

タイムゾーンと IoT デバイスの背景

  • UTC とローカルタイムの違い
    IoT デバイスでは UTC を基準に運用することが一般的ですが、ユーザーにローカルタイムを表示する必要がある場合も多いです。
  • Nerves プロジェクトでのタイム管理の課題
    • 組み込みシステムではタイムゾーンデータベースが省かれることが多く、ローカルタイムの取得が困難。
    • Nerves デバイスは RTC(リアルタイムクロック)が搭載されていない場合があり、ネットワーク経由での同期に依存。
  • 既存のアプローチ
    • /etc/timezone ファイルの設定や Timex.Timezone.Local を使用する方法があるが、設定の煩雑さやサイズの大きさが課題。

NervesTimeZones が解決する課題

  • 軽量で効率的なタイムゾーンデータ管理
    • 従来の tzdata や tz パッケージと比較してデータベースのサイズを大幅に削減。
    • タイムゾーンデータベースから必要な期間のみに絞ったデータを使用。
  • デバイス全体での一貫性あるタイムゾーン設定
    • Erlang/Elixir のタイムゾーン機能をサポートするだけでなく、非 BEAM プログラムでも同じデータベースを利用可能。
  • 設定の永続化と柔軟性
    • デバイスの再起動後も設定を保持。
    • デフォルトのタイムゾーンやデータ期間を柔軟に変更可能。

基本的な使い方

1. インストール

mix.exs に以下を追加します。

mix.exs
def deps do
  [
    {:nerves_time_zones, "~> 0.3.2"}
  ]
end

2. 初期設定

config/config.exsでタイムゾーンの初期値を設定します。何も指定しない場合はUTCが使用されます。

config/config.exs
config :nerves_time_zones, default_time_zone: "Asia/Tokyo"

3. タイムゾーンの変更

実行時にタイムゾーンの変更したい場合は、NervesTimeZones.set_time_zone/1 を使ってタイムゾーンを設定します。

# 現在使用されているタイムゾーンを表示
iex> NervesTimeZones.get_time_zone()

# タイムゾーンを変更
iex> NervesTimeZones.set_time_zone("America/New_York")

# タイムゾーンを初期値に戻す
iex> NervesTimeZones.reset_time_zone()

NervesTimeZones には他にも便利な関数があります。

# 使用可能なタイムゾーン名リストを表示
iex> NervesTimeZones.time_zones()
["Africa/Abidjan", "Africa/Accra", "Africa/Addis_Ababa", "Africa/Algiers", ...

# タイムゾーン名が使用可能か確認
iex> NervesTimeZones.valid_time_zone?("Autoracex")
false

iex> NervesTimeZones.valid_time_zone?("Asia/Tokyo")
true

# nerves_time_zonesが使用するタイムゾーン関連の環境変数を表示。
iex> NervesTimeZones.tz_environment()
%{
  "TZ" => "/srv/erlang/lib/nerves_time_zones-0.1.10/priv/zoneinfo/America/New_York",
  "TZDIR" => "/srv/erlang/lib/nerves_time_zones-0.1.10/priv/zoneinfo"
}

実践例

ローカルタイムの取得と活用

タイムゾーン設定後、NaiveDateTime.local_now/0 でローカルタイムを取得できます。

iex> DateTime.now("America/New_York")
{:ok, #DateTime<2024-12-16 12:00:00-05:00 EST America/New_York>}

BEAM 外のプログラムでの使用

System.cmd/3env オプションでタイムゾーン環境を設定可能です。

iex> System.cmd("date", [], env: NervesTimeZones.tz_environment())
{"Mon Dec 16 12:00:00 EST 2024\n", 0}

他の選択肢との比較

ライブラリ 主な特徴 データサイズ (例) 主な使用例
tzdata - IANA データを内部フォーマット(ETS テーブル)に変換して管理
- 自動データ更新機能あり
~600 KB (gzip 圧縮: 300 KB) Web アプリや標準的なアプリ用途
tz - コンパイル済みの BEAM ファイル形式で管理
- サイズが小さいが自動更新機能はなし
~250 KB (gzip 圧縮: 200 KB) 軽量さを求める BEAM アプリ用途
zoneinfo - TZif ファイルを直接使用
- サイズが最も小さい
- 非 BEAM プログラムでも利用可能
~16 KB (gzip 圧縮) IoT デバイスや組み込みシステム
NervesTimeZones - zoneinfo を基盤に Nerves デバイス向けに最適化
- 設定の永続化が可能
- 自動更新機能はなし
~16 KB (zoneinfo に依存) Nerves デバイス専用

おわりに

NervesTimeZones は、Nerves デバイス上でローカルタイムやタイムゾーンを管理するための効率的で柔軟なソリューションです。ぜひプロジェクトに活用してみてください!

toukon-qiita-macbook_20230912_091808.jpg

6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?