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