2
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 3

DateTimeモジュール で遊んでみたシリーズ③ -DateTime.convert ~ DateTime.from_gregorian_seconds の紹介

Last updated at Posted at 2024-12-21

こんにちは!
プログラミング未経験文系出身、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モジュール で遊んでみたシリーズ番外編 -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.convertとは

DateTime.convert(datetime, calendar)datetimecalendar基準に変換したものを返します。
カレンダー間で明確に変換できない場合は{:error, :incompatible_calendars}を返します。

※前提としてcalendarの実装が必要です。
下記の例では現在のグレゴリオ暦に10000年を追加するカレンダーを実装しているとします。

iex
dt1 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
                hour: 23, minute: 0, second: 7, microsecond: {0, 0},
                utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
iex
DateTime.convert(dt1, Calendar.Holocene)
{:ok, %DateTime{calendar: Calendar.Holocene, day: 29, hour: 23,
                microsecond: {0, 0}, minute: 0, month: 2, second: 7, std_offset: 0,
                time_zone: "America/Manaus", utc_offset: -14400, year: 12000,
                zone_abbr: "AMT"}}

DateTime.convert!とは

DateTime.convert(datetime, calendar)datetimecalendar基準に変換したものを返します。
カレンダー間で明確に変換できない場合はArgumentErrorを返します。

※前提としてcalendarの実装が必要です。
下記の例では現在のグレゴリオ暦に10000年を追加するカレンダーを実装しているとします。

iex
dt1 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
                hour: 23, minute: 0, second: 7, microsecond: {0, 0},
                utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
iex
DateTime.convert!(dt1, Calendar.Holocene)

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

%DateTime{calendar: Calendar.Holocene, day: 29, hour: 23,
          microsecond: {0, 0}, minute: 0, month: 2, second: 7, std_offset: 0,
          time_zone: "America/Manaus", utc_offset: -14400, year: 12000,
          zone_abbr: "AMT"}

DateTime.diffとは

DateTime.diff(datetime1, datetime2, unit \\ :second)datetime1からdatetime2を減算します。
結果はunit単位で返されます。

iex
DateTime.diff(~U[2024-01-15 10:00:10Z], ~U[2024-01-15 10:00:00Z])
10

datetime1よりもdatetime2が大きい場合

iex
DateTime.diff(~U[2024-01-15 10:00:00Z], ~U[2024-01-15 10:00:10Z])
-10

unitを変更した場合

小数の結果はサポートされておらず、切り捨てられます。

unit変更前。2つのDatetime構造体には「1日(=86400秒) + 10秒」の差分があります。

iex
DateTime.diff(~U[2024-01-16 10:00:10Z], ~U[2024-01-15 10:00:00Z])
86410

unit変更後。10秒の差分が切り捨てられました。

iex
DateTime.diff(~U[2024-01-16 10:00:10Z], ~U[2024-01-15 10:00:00Z], :day)
1

DateTime.from_gregorian_secondsとは

DateTime.from_gregorian_seconds(seconds, arg \\ {0, 0}, calendar \\ Calendar.ISO)は現在のグレゴリオ暦基準で、secondsをDatetime構造体に変換します。

seconds特定の日付と時刻を秒数で示し、argで1秒以下の時刻を示します。

タイムゾーンはUTCで返されます。
UTC以外のタイムゾーンが必要な場合は、この関数の結果に対してDateTime.shift_zone/3を使用してタイムゾーンを変換してください。

この関数の逆はDateTime.to_gregorian_seconds(datetime)です。

iex
DateTime.from_gregorian_seconds(1)
~U[0000-01-01 00:00:01Z]
iex
DateTime.from_gregorian_seconds(63_872_532_000)
~U[2024-01-15 10:00:00Z]

余談

ISO 8601形式で0000年は現実の紀元前1年を指します。
現実には紀元1年の前は紀元前1年ですが、コンピュータにとって算術のしやすさを優先しています1

~Elixirの国のご案内~

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

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

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

  1. https://ja.wikipedia.org/wiki/0%E5%B9%B4#%E8%A5%BF%E6%9A%A60%E5%B9%B4

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

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

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