Time in Elixir

Our first example demonstrates Elixir’s extensive support for times and durations. Let’s explore various time-related operations.

defmodule TimeExample do
  def run do
    # We'll start by getting the current time.
    now = DateTime.utc_now()
    IO.inspect(now)

    # You can build a DateTime struct by providing the
    # year, month, day, etc. Times are always associated
    # with a time zone.
    then = DateTime.new!(~D[2009-11-17], ~T[20:34:58.651387237], "Etc/UTC")
    IO.inspect(then)

    # You can extract the various components of the time
    # value as expected.
    IO.puts(then.year)
    IO.puts(then.month)
    IO.puts(then.day)
    IO.puts(then.hour)
    IO.puts(then.minute)
    IO.puts(then.second)
    IO.puts(then.microsecond |> elem(0))
    IO.puts(then.time_zone)

    # The day of the week is also available.
    IO.puts(Date.day_of_week(DateTime.to_date(then)))

    # These functions compare two times, testing if the
    # first occurs before, after, or at the same time
    # as the second, respectively.
    IO.puts(DateTime.compare(then, now) == :lt)
    IO.puts(DateTime.compare(then, now) == :gt)
    IO.puts(DateTime.compare(then, now) == :eq)

    # The diff function returns a Duration representing
    # the interval between two times.
    diff = DateTime.diff(now, then, :microsecond)
    IO.puts("#{diff} microseconds")

    # We can compute the length of the duration in
    # various units.
    IO.puts("#{diff / 1_000_000 / 3600} hours")
    IO.puts("#{diff / 1_000_000 / 60} minutes")
    IO.puts("#{diff / 1_000_000} seconds")
    IO.puts("#{diff} microseconds")

    # You can use add to advance a time by a given
    # duration, or with a negative value to move backwards.
    IO.inspect(DateTime.add(then, div(diff, 1_000_000), :second))
    IO.inspect(DateTime.add(then, -div(diff, 1_000_000), :second))
  end
end

TimeExample.run()

To run the program, save it as time_example.exs and use elixir:

$ elixir time_example.exs
#DateTime<2023-06-04 12:34:56.789123Z>
#DateTime<2009-11-17 20:34:58.651387Z>
2009
11
17
20
34
58
651387
Etc/UTC
3
true
false
false
427107358137736 microseconds
118641.48837159333 hours
7118489.302295561 minutes
427109358.137736 seconds
427109358137736 microseconds
#DateTime<2023-06-04 12:34:58.651387Z>
#DateTime<1996-05-02 04:34:58.651387Z>

Next, we’ll look at the related idea of time relative to the Unix epoch.

Note: Elixir’s DateTime module doesn’t have direct equivalents for all of Go’s time functions, but it provides similar functionality. The main differences are in how durations are handled and some specific time comparisons.