如何从当前日期和Ecto.Date实例中获得多年的差异

问题描述 投票:3回答:2

假设我有一个Person模型,每个人都有一个生日字段设置为Ecto.Date列。

因此,如果我从数据库中检索表示此模型实例的记录,那么从他的birthday列中获取此人年龄的最佳方法是什么?

elixir phoenix-framework ecto
2个回答
1
投票

不确定'最佳方式',但这是一种方式:

defmodule AgeCalc do
  @spec age(Ecto.Date.t, atom|{integer, integer, integer}) :: integer
  def age(%Ecto.Date{day: d, month: m, year: y}, as_of \\ :now) do
    do_age({y, m, d}, as_of)
  end

  ###########
  # Internals
  ###########
  @doc false
  def do_age(birthday, :now) do
    {today, _time} = :calendar.now_to_datetime(:erlang.now)
    calc_diff(birthday, today)
  end
  def do_age(birthday, date), do: calc_diff(birthday, date)

  @doc false
  def calc_diff({y1, m1, d1}, {y2, m2, d2}) when m2 > m1 or (m2 == m1 and d2 >= d1) do
    y2 - y1
  end
  def calc_diff({y1,_,_}, {y2,_,_}), do: (y2 - y1) - 1
end

用法如下:(今天是2015年9月27日)

iex(1)> AgeCalc.age(%Ecto.Date{day: 27, month: 9, year: 2000})
15
iex(2)> AgeCalc.age(%Ecto.Date{day: 28, month: 9, year: 2000})
14

或者,对于今天以外的其他事项进行人工计算:

iex(3)> AgeCalc.age(%Ecto.Date{day: 28, month: 9, year: 2000}, {2034, 12, 25})
34

0
投票

我使用Ecto的Query API中的fragment。我有一个带有生日列的用户表,并使用以下查询:

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

该查询返回带有字段%Postgrex.Interval{}daysmonthssecs。需要几个月和div到12岁才能达到这个年龄。

我喜欢Timex,但使用Postgres的本地age功能对我来说似乎更清洁,更快捷。

© www.soinside.com 2019 - 2024. All rights reserved.