Dates and Times

Elixir Date, Time, DateTime, NaiveDateTime, and Duration handling

Elixir provides four date/time structs and a Duration module for time arithmetic.

Structs

Struct Contains Timezone Example
Date Year, month, day No ~D[2024-01-15]
Time Hour, minute, second, microsecond No ~T[14:30:00.000000]
NaiveDateTime Date + time No ~N[2024-01-15 14:30:00]
DateTime Date + time + timezone Yes ~U[2024-01-15 14:30:00Z]
Duration Time span Duration.new(hour: 2)

Creating dates and times

# From sigils
~D[2024-06-15]
~T[14:30:00]
~N[2024-06-15 14:30:00]
~U[2024-06-15 14:30:00Z]

# From structs
Date.new!(2024, 6, 15)
Time.new!(14, 30, 0)
NaiveDateTime.new!(2024, 6, 15, 14, 30, 0)
DateTime.new!(~D[2024-06-15], ~T[14:30:00], "Etc/UTC")

# From strings
Date.from_iso8601!("2024-06-15")
Time.from_iso8601!("14:30:00")
NaiveDateTime.from_iso8601!("2024-06-15 14:30:00")
DateTime.from_iso8601!("2024-06-15T14:30:00Z")

# Current
Date.utc_today()            # => ~D[2024-06-15]
Time.utc_now()              # => ~T[14:30:00.000000]
NaiveDateTime.utc_now()     # => ~N[2024-06-15 14:30:00.000000]
DateTime.utc_now()          # => ~U[2024-06-15 14:30:00Z]

Date functions

d = ~D[2024-06-15]

Date.day_of_week(d)         # => 6 (Saturday)
Date.day_of_year(d)          # => 167
Date.days_in_month(d)        # => 30
Date.quarter(d)              # => 2
Date.leap_year?(d)           # => true (2024 is a leap year)

# Arithmetic
Date.add(d, 7)               # => ~D[2024-06-22]
Date.add(d, -1)              # => ~D[2024-06-14]

# Difference
Date.diff(~D[2024-06-22], ~D[2024-06-15])  # => 7

# Comparison
Date.compare(~D[2024-01-01], ~D[2024-06-15])  # => :lt
Date.compare(~D[2024-06-15], ~D[2024-06-15])  # => :eq

# Formatting
Calendar.strftime(d, "%B %d, %Y")  # => "June 15, 2024"

# Parsing
Date.from_iso8601!("2024-06-15")

Time functions

t = ~T[14:30:00]

Time.add(t, 3600, :second)    # => ~T[15:30:00]
Time.diff(~T[16:00:00], t)    # => 5400 (seconds)

Time.hour(t)                    # => 14
Time.minute(t)                  # => 30
Time.second(t)                  # => 0

DateTime functions

dt = DateTime.utc_now()

# Timezone conversion
{:ok, pacific} = DateTime.shift_zone(dt, "America/Los_Angeles")

# Arithmetic
DateTime.add(dt, 3600, :second)  # +1 hour

# Difference
DateTime.diff(dt2, dt1)  # difference in seconds

Duration

# Creating durations
d = Duration.new!(year: 1, month: 2, day: 3)
# => %Duration{year: 1, month: 2, day: 3, ...}

# Adding duration to date/time
Date.add(~D[2024-01-15], Duration.new!(day: 30))
# => ~D[2024-02-14]

NaiveDateTime.add(~N[2024-01-15 12:00:00], Duration.new!(hour: 2, minute: 30))
# => ~N[2024-01-15 14:30:00]

# Subtracting
NaiveDateTime.add(~N[2024-01-15 14:30:00], Duration.new!(hour: -2))
# => ~N[2024-01-15 12:30:00]

strftime format codes

Commonly used format codes for Calendar.strftime/2:

Code Meaning Example
%Y 4-digit year 2024
%y 2-digit year 24
%m Month (zero-padded) 06
%d Day (zero-padded) 15
%B Full month name June
%b Short month name Jun
%A Full weekday name Saturday
%a Short weekday name Sat
%H Hour 24h (zero-padded) 14
%I Hour 12h (zero-padded) 02
%M Minute (zero-padded) 30
%S Second (zero-padded) 00
%p AM/PM PM
%Z Timezone name UTC