'How to get difference in years from current date and Ecto.Date instance

Let's say I have a Person model and each person has a birthday field set as an Ecto.Date column.

So if I retrieve a record from the database which represents an instance of this model, what is the best way to get this person's age from his birthday column?



Solution 1:[1]

I use fragment from Ecto's Query API. I have a user table with a birthday column and am using the following query:

Repo.all(from u in User, select: fragment("age(?)", u.birthday))

The query returns a %Postgrex.Interval{} with fields days, months, and secs. Take months and div by 12 to get the age.

I love Timex but using Postgres' native age function seems cleaner and quicker to me.

Solution 2:[2]

I did it in elixir like this

  def calculate_age(dob) when is_binary(dob)
  def calculate_age(dob) when is_binary(dob) do
    today = Date.utc_today()
    dob = Date.from_iso8601! dob
    today.year - dob.year
  end

Solution 3:[3]

I know this is a bit old but I just ran into this and wrote my own function which I think is a bit easier to understand, using Date from Elixir which has since replaced Ecto.Date:

def get_person_age(%Person{} = person) do
  today = Date.utc_today()
  {:ok, today_in_birthday_year} = Date.new(person.birthday.year, today.month, today.day)
  years_diff = today.year - person.birthday.year

  if Date.compare(today_in_birthday_year, person.birthday) == :lt do
    years_diff - 1
  else
    years_diff
  end
end

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Chetan Shenoy
Solution 2 Tenzil
Solution 3 gcpreston