Packages
hl7v2
1.1.0
3.10.1
3.9.0
3.8.0
3.7.0
3.6.0
3.5.0
3.4.0
3.3.6
3.3.5
3.3.4
3.3.3
3.3.2
3.3.1
3.3.0
3.2.0
3.1.1
3.1.0
3.0.2
3.0.1
3.0.0
2.11.0
2.10.0
2.9.1
2.9.0
2.8.2
2.8.1
2.8.0
2.7.1
2.7.0
2.6.0
2.5.0
2.4.0
2.3.0
2.2.0
2.1.3
2.1.2
2.1.1
2.1.0
1.4.6
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.0
1.2.0
1.1.0
1.0.0
0.6.0
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.1.0
Pure Elixir HL7 v2.x toolkit — schema-driven parsing, typed segments, message builder, MLLP transport
Current section
Files
Jump to
Current section
Files
lib/hl7v2/type/dt.ex
defmodule HL7v2.Type.DT do
@moduledoc """
Date (DT) -- HL7v2 primitive data type.
Format: `YYYY[MM[DD]]`. Supports year, month, and day precision.
Parses to an `%HL7v2.Type.DT{}` struct preserving precision, or a `Date`
when full day precision is available.
"""
@behaviour HL7v2.Type
defstruct [:year, :month, :day]
@type t :: %__MODULE__{
year: pos_integer(),
month: pos_integer() | nil,
day: pos_integer() | nil
}
@doc """
Parses a date string in `YYYY[MM[DD]]` format.
Returns a `Date` struct when fully specified (8 digits), or an
`%HL7v2.Type.DT{}` struct for partial dates.
## Examples
iex> HL7v2.Type.DT.parse("19880704")
~D[1988-07-04]
iex> HL7v2.Type.DT.parse("199503")
%HL7v2.Type.DT{year: 1995, month: 3, day: nil}
iex> HL7v2.Type.DT.parse("2026")
%HL7v2.Type.DT{year: 2026, month: nil, day: nil}
iex> HL7v2.Type.DT.parse("")
nil
iex> HL7v2.Type.DT.parse(nil)
nil
"""
@spec parse(binary() | nil) :: Date.t() | t() | nil
def parse(nil), do: nil
def parse(""), do: nil
def parse(<<y::binary-size(4), m::binary-size(2), d::binary-size(2)>>) do
with {year, ""} <- Integer.parse(y),
{month, ""} <- Integer.parse(m),
{day, ""} <- Integer.parse(d),
{:ok, date} <- Date.new(year, month, day) do
date
else
_ -> nil
end
end
def parse(<<y::binary-size(4), m::binary-size(2)>>) do
with {year, ""} <- Integer.parse(y),
{month, ""} <- Integer.parse(m),
true <- month in 1..12 do
%__MODULE__{year: year, month: month}
else
_ -> nil
end
end
def parse(<<y::binary-size(4)>>) do
case Integer.parse(y) do
{year, ""} when year > 0 -> %__MODULE__{year: year}
_ -> nil
end
end
def parse(_), do: nil
@doc """
Encodes a date value to `YYYYMMDD`, `YYYYMM`, or `YYYY` format.
## Examples
iex> HL7v2.Type.DT.encode(~D[1988-07-04])
"19880704"
iex> HL7v2.Type.DT.encode(%HL7v2.Type.DT{year: 1995, month: 3})
"199503"
iex> HL7v2.Type.DT.encode(%HL7v2.Type.DT{year: 2026})
"2026"
iex> HL7v2.Type.DT.encode(nil)
""
"""
@spec encode(Date.t() | t() | nil) :: binary()
def encode(nil), do: ""
def encode(%Date{year: y, month: m, day: d}) do
pad4(y) <> pad2(m) <> pad2(d)
end
def encode(%__MODULE__{year: y, month: nil}) do
pad4(y)
end
def encode(%__MODULE__{year: y, month: m, day: nil}) do
pad4(y) <> pad2(m)
end
def encode(%__MODULE__{year: y, month: m, day: d}) do
pad4(y) <> pad2(m) <> pad2(d)
end
defp pad4(n), do: n |> Integer.to_string() |> String.pad_leading(4, "0")
defp pad2(n), do: n |> Integer.to_string() |> String.pad_leading(2, "0")
end