49 lines
1.4 KiB
Elixir

defmodule Growth.Calc.Age do
@moduledoc """
Calculate the age in months.
"""
@type precision :: :day | :week | :month | :year
# NOTE: (jpd): based on [WHO instructions][0]
# [0]: https://cdn.who.int/media/docs/default-source/child-growth/child-growth-standards/indicators/instructions-en.pdf
@day_in_month 30.4375
@day_in_week 7.0
@doc """
Calculate the age with the precision of `:day`, or `:week`, or `:month`, considering the measurement date as today.
For age in weeks or months, considers completed ones, removing decimal value.
"""
@spec calculate(precision(), Date.t(), Date.t()) :: pos_integer()
def calculate(precision, date_of_birth) do
calculate(precision, date_of_birth, Date.utc_today())
end
@doc """
Calculate the age with the precision of `:day`, or `:week`, or `:month`.
For age in weeks or months, considers completed ones, removing decimal value.
"""
def calculate(:month, date_of_birth, date_of_measurement) do
:day
|> calculate(date_of_birth, date_of_measurement)
|> Kernel./(@day_in_month)
|> floor()
end
def calculate(:week, date_of_birth, date_of_measurement) do
:day
|> calculate(date_of_birth, date_of_measurement)
|> Kernel./(@day_in_week)
|> floor()
end
def calculate(:day, date_of_birth, date_of_measurement) do
Date.diff(date_of_measurement, date_of_birth)
end
end