如何在Elixir中实现Date.add(date,n,:month)

时间:2019-06-26 12:22:23

标签: date elixir

很高兴将其包含在标准Elixir库中,但我们没有。

Date.add(date, n, :month) # where n could be +/-

您将如何实施?

这似乎是一个很好的起点:https://stackoverflow.com/a/53407676/44080

4 个答案:

答案 0 :(得分:1)

您可以使用the Timex implementation

  defp shift_by(%NaiveDateTime{:year => year, :month => month} = datetime, value, :months) do
    m = month + value
    shifted =
      cond do
        m > 0 ->
          years = div(m - 1, 12)
          month = rem(m - 1, 12) + 1
          %{datetime | :year => year + years, :month => month}
        m <= 0 ->
          years = div(m, 12) - 1
          month = 12 + rem(m, 12)
          %{datetime | :year => year + years, :month => month}
      end

    # If the shift fails, it's because it's a high day number, and the month
    # shifted to does not have that many days. This will be handled by always
    # shifting to the last day of the month shifted to.
    case :calendar.valid_date({shifted.year,shifted.month,shifted.day}) do
      false ->
        last_day = :calendar.last_day_of_the_month(shifted.year, shifted.month)
        cond do
          shifted.day <= last_day ->
            shifted
          :else ->
            %{shifted | :day => last_day}
        end
      true ->
        shifted
    end
  end

Timex uses the MIT license,因此您应该几乎可以将其合并到任何项目中。

答案 1 :(得分:1)

Date.utc_today() |> Timex.shift(months: -1) 

答案 2 :(得分:0)

有一个长生不老药功能Date.add/2。给它任何日期,它将为您添加日期。

iex>Date.add(~D[2000-01-03], -2)
~D[2000-01-01]

如果您想创建要添加的日期,那么我建议您使用Date.new/4

iex>{:ok, date} = Date.new(year, month, day) 
iex>date |> Date.add(n)

答案 3 :(得分:0)

ex_cldr_calendars 还可以对实现 Calendar 行为的任何日历进行基本的日期数学运算,用于添加和减去年、季度、月、周和日。

iex> Cldr.Calendar.plus ~D[2019-03-31], :months, -1
~D[2019-02-28]

# The :coerce option determines whether to force an end
# of month date when the result of the operation is an invalid date
iex> Cldr.Calendar.plus ~D[2019-03-31], :months, -1, coerce: false
{:error, :invalid_date}