LoginSignup
1
0

アプリケーションロジックでtime型を扱う際のTips

Posted at

この記事は、Go 言語 Advent Calendar 2023 の21日目の記事です。

Go言語で時間を扱う際の実装のTipsを2つ紹介します。これらは筆者の個人的な経験に基づくものであり、必ずしもすべてのケースに当てはまるわけではありません。

それでは、本題に入っていきましょう

Tips1 引数名

time.Time 型の値を引数として受け取る関数を作成する際の引数名について考えます。

func funcA(now time.Time){
    return
}

関数の呼び出しを考えると、以下のように処理が始まるタイミングでtime.Time型の変数を初期化、funcAに渡すと思います。

now := time.Now()
funcA(now)

nowという引数名にも違和感がないですね

その際に1点考えて欲しいことが「funcAが受け取るtime.Timeは、必ずしも現在時刻を期待するのか? 」ということです。

現在時刻を渡すような使用しかしていない場合でも、funcAの処理自体は現在時刻をマストとして期待していない(指定された日時をもとに処理を実行するだけ)という意味合いであれば、引数名はnowではなく、tが適切なのかもしれません。

Tips2 タイムゾーン

アプリケーションでの時間比較処理におけるタイムゾーンの扱いについて考察します。

時間比較処理には以下のようなシーンが考えられます。

  • アプリケーションコードにハードコーディングされている日時との比較
  • DBから取得したレコードの時刻型との比較
  • などなど

時間比較処理において、time.Time と string を変換する際、time.Time はタイムゾーンを自動的に扱いますが、string への変換ではタイムゾーン情報が失われてしまうことです。

つまりtime.Time同士で比較をする場合、タイムゾーンは開発者が意識しなくてもうまく変換してくれます。
しかし、time.TimeStringの変換を介している場合、タイムゾーン情報は保持されません。

例えば、日付をプレフィックスとして持つID(例:2023-12-01-Xxxxx)を現在時刻と比較するシーンがあります。
(マスターデータのIDにプレフィックスとして日付を持たせるケースはよく目にします)

そんなときにcloud.google.com/go/civilパッケージが有用です。提供される時間型(civil.Datecivil.Time)はタイムゾーン情報を持たないため、日付のみを扱う場合の比較が容易になります。

そのため、例に挙げたようなマスターデータのプレフィックスを時刻型としてパースする場合は、civil.Dateに変換し、変換対象のtime.Time型の値もcivil.Dateに変換し、比較することができます。

しかし以下の点に注意する必要があります

  • time から civil への変換時にどのタイムゾーンを使用するか
  • string で持たせる日時データがどのタイムゾーンを前提としているか

これらのルールをプロジェクト内で定めることで、時間比較を正確に行うことが可能になります。

1
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
1
0