2015-09-27 58 views

回答

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

我認爲那樣做會好,謝謝 – JustMichael

+0

有幾個用於通用日期/時間計算的庫。 Timex是我熟悉的一個。 https://github.com/bitwalker/timex –

+0

我經常使用vanilla Timex,通過查找我發現的文檔[:timex_ecto](https://timex.readme.io/docs/using-with-ecto),這看起來似乎這是一個很好的選擇,儘管我自己並沒有使用它,並且可能需要根據示例進行相當數量的重新加工。 –

相關問題