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 5

DateTimeモジュール で遊んでみたシリーズ⑤ -DateTime.from_unix ~ DateTime.new! の紹介

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.from_unixとは

DateTime.from_unix(integer, unit \\ :second, calendar \\ Calendar.ISO)integerで示したUNIX時間1を、Datetime構造体に変換します。
この関数のタイムゾーンはUTCで返されます(UNIX時間にはタイムゾーン情報が含まれないため)

この関数の逆はDateTime.to_unix(datetime, unit \\ :second)です。

iex
DateTime.from_unix(1_464_096_368)
{:ok, ~U[2016-05-24 13:26:08Z]}

integerは最大253,402,300,799秒がサポートされます。
これを超える場合{:error, :invalid_unix_time}のタプルが返されます。

iex
DateTime.from_unix(253_402_300_799)
{:ok, ~U[9999-12-31 23:59:59Z]}
iex
DateTime.from_unix(253_402_300_800)
{:error, :invalid_unix_time}

unitSystem.time_unit()でサポートされているものが使用できます。

iex
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時間にはタイムゾーン情報が含まれないため)

iex
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が返されます。

iex
DateTime.from_unix!(253_402_300_799)
~U[9999-12-31 23:59:59Z]
iex
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)

unitSystem.time_unit()でサポートされているものが使用できます。

iex
DateTime.from_unix!(1_432_560_368_868_569, :microsecond)
~U[2015-05-25 13:26:08.868569Z]

integer0を渡すと簡単にUNIXエポックを取得できます。

iex
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)と照合します。

iex
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直後の有効な日時}のタプルが返されます。

iex
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)と照合します。

iex
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を返します。

iex
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は先端のアレコレをだいたい全部できちゃいます:laughing::sparkles::sparkles:

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

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

  1. 起点が1970年1月1日00:00:00(UTC)にある。起点からの経過秒数で特定の日時を表現する https://wa3.i-3-i.info/word18474.html 2 3

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

  3. @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?