Specifying type of timestamps to :date result in UndefinedFunctionError

Hi,

I have a schema where I have the timestamps fields defined like this

timestamps(updated_at: false)

I have created a migration to change the type:

  def up do
    alter table("notifiable_events") do
      modify :inserted_at, :date, null: false
    end

    create unique_index(:notifiable_events, [:invoice_id, :reason, :inserted_at])
  end

Now when I change the field definition to

    timestamps(updated_at: false, type: :date)

as specified in the documentation, I get an error:

     ** (UndefinedFunctionError) function :date.from_unix!/2 is undefined (module :date is not available)
     code: perform_job(DunningStarter, %{})
     stacktrace:
       :date.from_unix!(1671025691354039, :microsecond)
       (ecto 3.9.2) lib/ecto/repo/schema.ex:965: anonymous fn/2 in Ecto.Repo.Schema.autogenerate_changes/3
       (elixir 1.14.0) lib/enum.ex:4249: Enum.flat_map_list/2

What did I miss ?

Edit: as a workaround, I’ve added the autogenerate option

    timestamps(updated_at: false, type: :date, autogenerate: {Date, :utc_today, []})

It works but am I always supposed to add the autogenerate option ?

Those fields are meant to have a time component, so the default functions Ecto uses will assume that. If you pass Date you’re giving it a type that is not compatible.

The is the behaviour Ecto uses:

def __timestamps__(:naive_datetime) do
  %{NaiveDateTime.utc_now() | microsecond: {0, 0}}
end

def __timestamps__(:naive_datetime_usec) do
  NaiveDateTime.utc_now()
end

def __timestamps__(:utc_datetime) do
  %{DateTime.utc_now() | microsecond: {0, 0}}
end

def __timestamps__(:utc_datetime_usec) do
  DateTime.utc_now()
end

def __timestamps__(type) do
  type.from_unix!(System.os_time(:microsecond), :microsecond)
end

You’re passing it :date s it’s going to the last pattern and failing because the Date module doesn’t a have from_unix! function