Bottom line is to use the following:
-
MIGRATION:
timestamptzaka.timestamp with timezone(the Ecto default istimestampand:naive_datetime) -
SCHEMA:
:utc_datetime(the Ecto default is:naive_datetime
Basically none of the recommended types are the default.
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()
endThe 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
endThe 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]
endend end
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
-
DateTimein Elixir "only handles "Etc/UTC" datetimes" but it can be configured with a custom time zone database, which is what thetzdatalibrary 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