5
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 6

DateTimeモジュール で遊んでみたシリーズ⑥ -DateTime.now ~ DateTime.shift_zone! の紹介

Last updated at Posted at 2024-12-22

こんにちは!
プログラミング未経験文系出身、Elixirの国に迷い込んだ?!見習いアルケミストのaliceと申します。
今回はDateTimeモジュールについて学んだことをまとめます。

目次

1.DateTimeモジュール で遊んでみたシリーズ① -事前準備編
2.DateTimeモジュール で遊んでみたシリーズ② -DateTime.add ~ DateTime.compare の紹介
3.DateTimeモジュール で遊んでみたシリーズ③ -DateTime.convert ~ DateTime.from_gregorian_seconds の紹介
4.DateTimeモジュール で遊んでみたシリーズ④ -DateTime.from_iso8601 ~ DateTime.from_naive! の紹介
5.DateTimeモジュール で遊んでみたシリーズ⑤ -DateTime.from_unix ~ DateTime.new! の紹介
6.DateTimeモジュール で遊んでみたシリーズ⑥ -DateTime.now ~ DateTime.shift_zone! の紹介(本記事)
7.DateTimeモジュール で遊んでみたシリーズ⑦ -DateTime.to_date ~ DateTime.to_string の紹介
8.DateTimeモジュール で遊んでみたシリーズ⑧ -DateTime.to_time ~ DateTime.utc_now の紹介
9.DateTimeモジュール で遊んでみたシリーズ番外編 -Livebookでtzdata導入

目的

DateTimeモジュールに含まれる関数を触って機能を理解したい

実行環境

Windows 11 + WSL2 + Ubuntu 22.04
Elixir v1.17.3
Erlang v27.0

前提

本記事を手元検証するには、前提としてtzdataの導入が必要です。
まだの場合は下記1.または2.で準備をしてください。

1.local環境でtzdataの導入

2.Livebookでtzdataの導入

DateTime.nowとは

DateTime.now(time_zone, time_zone_database \\ Calendar.get_time_zone_database())time_zoneの現在の日時を返します。
タイムゾーンはカレンダーデータベース(今回の場合はtzdata)と照合します。

iex
DateTime.now("Asia/Tokyo")
{:ok, #DateTime<2024-12-22 15:29:46.738383+09:00 JST Asia/Tokyo>}

time_zoneが存在しない場合{:error, :time_zone_not_found}のタプルを返します。

iex
DateTime.now("bad timezone")
{:error, :time_zone_not_found}

DateTime.now!とは

DateTime.now!(time_zone, time_zone_database \\ Calendar.get_time_zone_database())time_zoneの現在の日時を返します。
タイムゾーンはカレンダーデータベース(今回の場合はtzdata)と照合します。

成功した場合DateTime.now{:ok, Datetime構造体}タプル が返されるが、DateTime.now!Datetime構造体 が返されるので注意。

iex
DateTime.now!("Asia/Tokyo")
#DateTime<2024-12-22 15:32:34.231983+09:00 JST Asia/Tokyo>

カレンダーデータベースにタイムゾーンが見つからない場合ArgumentErrorを返します。

iex
DateTime.now!("bad timezone")
** (ArgumentError) cannot get current datetime in "bad timezone" time zone, reason: :time_zone_not_found
    (elixir 1.17.3) lib/calendar/datetime.ex:867: DateTime.now!/2
    #cell:p746o2eoytx56zax:1: (file)

DateTime.shiftとは

String.shift(datetime, duration, time_zone_database \\ Calendar.get_time_zone_database())datetimeduration分だけ調整します。このときdatetimeに含まれるタイムゾーンの
この関数の目的はそのタイムゾーンにいる人の時計を合わせる目的です。
つまり、サマータイムの開始/終了時刻といったイベント発生時に時計の調整をかけることができます。

iex
dt = DateTime.new!(~D[2025-03-09], ~T[01:59:00], "Asia/Tokyo")
#DateTime<2025-03-09 01:59:00+09:00 JST Asia/Tokyo>
iex
DateTime.shift(dt, hour: 1)
#DateTime<2025-03-09 02:59:00+09:00 JST Asia/Tokyo>

サマータイム開始/終了時刻をまたぐ場合

米国ニューヨークの次のサマータイム開始時刻は、現地時刻の3/9の02:00です。
このタイミングで時計が1時間進みます。
これをまたいで使用する場合時計が1時間進みます(秋に時計を1時間遅らせる場合も同様です)

iex
dt = DateTime.new!(~D[2025-03-09], ~T[01:59:00], "America/New_York")
#DateTime<2025-03-09 01:59:00-05:00 EST America/New_York>
iex
DateTime.shift(dt, hour: 1)
#DateTime<2025-03-09 03:59:00-04:00 EDT America/New_York>

DateTime.shift_zoneとは

DateTime.shift_zone(datetime, time_zone, time_zone_database \\ Calendar.get_time_zone_database())datetimeのタイムゾーンを変更します。
タイムゾーンはカレンダーデータベース(今回の場合はtzdata)と照合します。

iex
DateTime.shift_zone(~U[2018-07-16 10:00:00Z], "America/Los_Angeles", Tzdata.TimeZoneDatabase)
{:ok, #DateTime<2018-07-16 03:00:00-07:00 PDT America/Los_Angeles>}

カレンダーデータベースにタイムゾーンが見つからない場合{:error, :time_zone_not_found}のタプルを返します。

iex
DateTime.shift_zone(~U[2018-07-16 10:00:00Z], "bad timezone", Tzdata.TimeZoneDatabase)
{:error, :time_zone_not_found}

DateTime.shift_zone!とは

DateTime.shift_zone!(datetime, time_zone, time_zone_database \\ Calendar.get_time_zone_database())datetimeのタイムゾーンを変更します。
タイムゾーンはカレンダーデータベース(今回の場合はtzdata)と照合します。

成功した場合DateTime.shift_zone{:ok, Datetime構造体}タプル が返されるが、DateTime.shift_zone!Datetime構造体 が返されるので注意。

iex
DateTime.shift_zone!(~U[2018-07-16 10:00:00Z], "America/Los_Angeles", Tzdata.TimeZoneDatabase)
#DateTime<2018-07-16 03:00:00-07:00 PDT America/Los_Angeles>

カレンダーデータベースにタイムゾーンが見つからない場合ArgumentErrorを返します。

iex
DateTime.shift_zone!(~U[2018-07-16 10:00:00Z], "bad timezone", Tzdata.TimeZoneDatabase)
** (ArgumentError) cannot shift ~U[2018-07-16 10:00:00Z] to "bad timezone" time zone, reason: :time_zone_not_found
    (elixir 1.17.3) lib/calendar/datetime.ex:800: DateTime.shift_zone!/3
    #cell:azrdretu7avc4p3s:1: (file)

~Elixirの国のご案内~

↓Elixirって何ぞや?と思ったらこちらもどぞ。Elixirは先端のアレコレをだいたい全部できちゃいます:laughing::sparkles::sparkles:

↓ゼロからElixirを始めるなら「エリクサーチ」がおすすめ!私もエンジニア未経験から学習中です。

We Are The Alchemists, my friends!:bouquet:1
Elixirコミュニティは本当に優しくて温かい人たちばかり!
私が挫折せずにいられるのもこの恵まれた環境のおかげです。
まずは気軽にコミュニティを訪れてみてください。2

  1. @torifukukaiouさんのAwesomeな名言をお借りしました。Elixirコミュニティを一言で表すと、これに尽きます。

  2. @kn339264さんの素敵なスライドをお借りしました。Elixirコミュニティはいろんな形で活動中!

5
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
5
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?