Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate than one date is later or same than the other

I want to validate that ends_on is always later or the same date as starts_on. But my custom validation doesn't work. What is the correct way to write this validation?

defmodule Example.Calendar.VacationPeriod do
  use Ecto.Schema
  import Ecto.Changeset
  alias Example.Calendar.VacationPeriod

  schema "vacation_periods" do
    field :ends_on, :date
    field :name, :string
    field :starts_on, :date

    timestamps()
  end

  @doc false
  def changeset(%VacationPeriod{} = vacation_period, attrs) do
    vacation_period
    |> cast(attrs, [:name, :starts_on, :ends_on])
    |> validate_required([:name, :starts_on, :ends_on])
    |> validate_dates_make_sense
  end

  defp validate_dates_make_sense(changeset) do
    starts_on = get_field(changeset, :starts_on)
    ends_on = get_field(changeset, :ends_on)

    if starts_on > ends_on do
      add_error(changeset, :starts_on, "cannot be later than 'ends_on'")
    else
      changeset
    end
  end
end
like image 438
wintermeyer Avatar asked Sep 18 '17 14:09

wintermeyer


People also ask

How do you check if a date is less than another date?

To check if a date is before another date, compare the Date objects, e.g. date1 < date2 . If the comparison returns true , then the first date is before the second, otherwise the first date is equal to or comes after the second. Copied!

How do you validate the end date greater than the start date?

val(); var endDate = $('#end_date'). val(); if (endDate < startDate){ alert('End date should be greater than Start date. '); $('#end_date'). val(''); } });


1 Answers

You cannot compare Date structs using the comparison operators. The Date module has a compare/2 function you can use:

if Date.compare(starts_on, ends_on) == :gt do
  add_error(changeset, :starts_on, "cannot be later than 'ends_on'")
else
  changeset
end      

or with case:

case Date.compare(starts_on, ends_on) do
  :gt -> add_error(changeset, :starts_on, "cannot be later than 'ends_on'")
  _ -> changeset
end
like image 121
Dogbert Avatar answered Nov 15 '22 09:11

Dogbert