こんにちは!
プログラミング未経験文系出身、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.from_unixとは
DateTime.from_unix(integer, unit \\ :second, calendar \\ Calendar.ISO)
はinteger
で示したUNIX時間1を、Datetime構造体に変換します。
この関数のタイムゾーンはUTCで返されます(UNIX時間にはタイムゾーン情報が含まれないため)
この関数の逆はDateTime.to_unix(datetime, unit \\ :second)
です。
例
DateTime.from_unix(1_464_096_368)
{:ok, ~U[2016-05-24 13:26:08Z]}
integer
は最大253,402,300,799秒がサポートされます。
これを超える場合{:error, :invalid_unix_time}
のタプルが返されます。
DateTime.from_unix(253_402_300_799)
{:ok, ~U[9999-12-31 23:59:59Z]}
DateTime.from_unix(253_402_300_800)
{:error, :invalid_unix_time}
unit
はSystem.time_unit()
でサポートされているものが使用できます。
DateTime.from_unix(1_432_560_368_868_569, :microsecond)
{:ok, ~U[2015-05-25 13:26:08.868569Z]}
DateTime.from_unix!とは
DateTime.from_unix!(integer, unit \\ :second, calendar \\ Calendar.ISO)
はinteger
で示したUNIX時間1を、Datetime構造体に変換します。
この関数のタイムゾーンはUTCで返されます(UNIX時間にはタイムゾーン情報が含まれないため)
例
DateTime.from_unix!(1_464_096_368)
~U[2016-05-24 13:26:08Z]
変換に成功した場合DateTime.from_unix
は {:ok, Datetime構造体}
のタプル が返されるが、DateTime.from_unix!
は Datetime構造体 が返されるので注意。
integer
は最大253,402,300,799秒がサポートされます。
これを超える場合ArgumentError
が返されます。
DateTime.from_unix!(253_402_300_799)
~U[9999-12-31 23:59:59Z]
DateTime.from_unix!(253_402_300_800)
** (ArgumentError) invalid Unix time 253402300800
(elixir 1.17.3) lib/calendar/datetime.ex:475: DateTime.from_unix!/3
#cell:6bybjar5k2gh7jdi:1: (file)
unit
はSystem.time_unit()
でサポートされているものが使用できます。
DateTime.from_unix!(1_432_560_368_868_569, :microsecond)
~U[2015-05-25 13:26:08.868569Z]
integer
に0
を渡すと簡単にUNIXエポックを取得できます。
DateTime.from_unix!(0)
~U[1970-01-01 00:00:00Z]
DateTime.newとは
DateTime.new(date, time, time_zone \\ "Etc/UTC", time_zone_database \\ Calendar.get_time_zone_database())
はDate構造体とTime構造体を合わせてDatetime構造体に変換します。
タイムゾーンはカレンダーデータベース(今回の場合はtzdata)と照合します。
例
DateTime.new(~D[2016-05-24], ~T[13:26:08.003])
{:ok, ~U[2016-05-24 13:26:08.003Z]}
サマータイム開始/終了時刻をまたぐ場合
米国ニューヨークの次のサマータイム開始時刻1は、現地時刻の3/9の02:00です。
このタイミングで時計が1時間進みます[^2]
これをまたいで使用する場合{:gap, gap直前の有効な日時, gap直後の有効な日時}
のタプルが返されます。
DateTime.new(~D[2025-03-09], ~T[02:00:00.003], "America/New_York")
{:gap, #DateTime<2025-03-09 01:59:59.999999-05:00 EST America/New_York>,
#DateTime<2025-03-09 03:00:00-04:00 EDT America/New_York>}
DateTime.new!とは
DateTime.new!(date, time, time_zone \\ "Etc/UTC", time_zone_database \\ Calendar.get_time_zone_database())
はDate構造体とTime構造体を合わせてDatetime構造体に変換します。
タイムゾーンはカレンダーデータベース(今回の場合はtzdata)と照合します。
例
DateTime.new!(~D[2016-05-24], ~T[13:26:08.003])
~U[2016-05-24 13:26:08.003Z]
変換に成功した場合DateTime.new
は {:ok, Datetime構造体}
のタプル が返されるが、DateTime.new!
は Datetime構造体 が返されるので注意。
サマータイム開始/終了時刻をまたぐ場合
米国ニューヨークの次のサマータイム開始時刻は、現地時刻の3/9の02:00です。
このタイミングで時計が1時間進みます
これをまたいで使用する場合ArgumentError
を返します。
DateTime.new!(~D[2025-03-09], ~T[02:00:00.003], "America/New_York")
** (ArgumentError) cannot build datetime with ~D[2025-03-09] and ~T[02:00:00.003] because such instant does not exist in time zone America/New_York as there is a gap between #DateTime<2025-03-09 01:59:59.999999-05:00 EST America/New_York> and #DateTime<2025-03-09 03:00:00-04:00 EDT America/New_York>
(elixir 1.17.3) lib/calendar/datetime.ex:363: DateTime.new!/4
#cell:nnmq33fxksvkuzxj:1: (file)
~Elixirの国のご案内~
↓Elixirって何ぞや?と思ったらこちらもどぞ。Elixirは先端のアレコレをだいたい全部できちゃいます
↓ゼロからElixirを始めるなら「エリクサーチ」がおすすめ!私もエンジニア未経験から学習中です。
↓We Are The Alchemists, my friends!2
Elixirコミュニティは本当に優しくて温かい人たちばかり!
私が挫折せずにいられるのもこの恵まれた環境のおかげです。
まずは気軽にコミュニティを訪れてみてください。3
-
起点が1970年1月1日00:00:00(UTC)にある。起点からの経過秒数で特定の日時を表現する https://wa3.i-3-i.info/word18474.html ↩ ↩2 ↩3
-
@torifukukaiouさんのAwesomeな名言をお借りしました。Elixirコミュニティを一言で表すと、これに尽きます。 ↩