Would like to use DateTime
in Ecto schemas and migrations, instead of the default NaiveDateTime
, and also timestamptz
in PostgreSQL, instead of the default timestamp
(aka. timestamp without time zone
).
timestamptz
and :utc_datetime
Note: Ecto.Migration.timestamps/1 (source) global configuration can always be overridden locally.
Using the :migration_timestamps
configuration option from the Ecto.Migration
docs:
# in ./config/dev.exs (for example)
config :app, App.Repo, migration_timestamps: [type: :timestamptz]
and one can use Ecto.Migration.timestamps/1
in migrations as usual:
# ./priv/repo/migrations/20190718195828_create_users.exs
create table(:users) do
add :username, :string, null: false
timestamps()
end
The Postgres
adapter will automatically switch
the Elixir representation to DateTime
from
NaiveDateTime
.
Use Ecto.Migration.timestamps/1's :type
option:
defmodule App.Repo.Migrations.CreateUsers do
use Ecto.Migration
def change do
create table(:users) do
add :username, :string, null: false
timestamps(type: :timestamptz)
end
end
end
:utc_datetime
The Ecto schemas also need to be modified to
use :utc_datetime
, otherwise they will expect
NaiveDateTime
by default. Slightly modifying the
example in the
Ecto.Schema
docs:
# Define a module to be used as base defmodule MyApp.Schema do defmacro __using__(_) do quote do use Ecto.Schema # In case one uses UUIDs @primary_key {:id, :binary_id, autogenerate: true} @foreign_key_type :binary_id # ------------------------------------ @timestamps_opts [type: :utc_datetime] end end end # Now use MyApp.Schema to define new schemas defmodule MyApp.Comment do use MyApp.Schema schema "comments" do belongs_to :post, MyApp.Post timestamps() end end
defmodule ANV.Accounts.User do
use Ecto.Schema
# -- EITHER --------------------------
@timestamps_opts [type: :utc_datetime]
schema "users" do
field :username, :string
# -- OR -----------------------
timestamps(type: :utc_datetime)
end
DateTime
in Elixir "only handles "Etc/UTC"
datetimes" but it can be configured with a custom
time zone database, which is what the tzdata
library is
Time zones in PostgreSQL, Elixir and Phoenix and How to set timestamps to UTC DateTimes in Ecto
A very handy table from the first article:
+----------------------+------------------+------------------------+------------------------------+-----------------------------------+
| Ecto 3 type | Elixir type | Supports microseconds? | Supports DateTime functions? | Supports NaiveDateTime functions? |
+----------------------+------------------+------------------------+------------------------------+-----------------------------------+
| :utc_datetime_usec | DateTime | YES | YES | YES |
| :utc_datetime | DateTime | NO | YES | YES |
| :naive_datetime_usec | NaiveDateTime | YES | NO | YES |
| :naive_datetime | NaiveDateTime | NO | NO | YES |
+----------------------+------------------+------------------------+------------------------------+-----------------------------------+
Discussions and advice specific to PostgreSQL