{"__v":3,"_id":"55ccdd944906d12f001226a3","category":{"__v":1,"_id":"55ccdd934906d12f00122699","pages":["55ccdd944906d12f0012269b","55ccdd944906d12f0012269c","55ccdd944906d12f0012269d","55ccdd944906d12f0012269e","55ccdd944906d12f0012269f","55ccdd944906d12f001226a0","55ccdd944906d12f001226a1","55ccdd944906d12f001226a2","55ccdd944906d12f001226a3"],"project":"5589b6c3acfab80d0072025e","version":"55ccdd924906d12f00122698","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-06-23T19:43:00.914Z","from_sync":false,"order":0,"slug":"documentation","title":"Documentation"},"project":"5589b6c3acfab80d0072025e","user":"5589b346986b6c0d00f54355","version":{"__v":1,"_id":"55ccdd924906d12f00122698","project":"5589b6c3acfab80d0072025e","createdAt":"2015-08-13T18:10:26.772Z","releaseDate":"2015-08-13T18:10:26.772Z","categories":["55ccdd934906d12f00122699","55ccdd934906d12f0012269a"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"0.19.0","version":"0.19"},"updates":[],"next":{"pages":[],"description":""},"createdAt":"2015-07-04T19:13:55.973Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":8,"body":"### Getting Started\n\nTimex has can be integrated with Ecto via the `timex_ecto` plugin which is available on hex.pm:\n\n```elixir\ndefp deps do\n  [{:timex, \"~> x.x.x\"},\n   {:timex_ecto, \"~> x.x.x\"}]\nend\n```\n\n### Available Types\n\nTimex-Ecto exposes a few different types for you to use:\n\n- `Timex.Ecto.Date`: An ISO date (`YYYY-MM-DD`)\n- `Timex.Ecto.Time`: An ISO time (`hh:mm:ss.sss`)\n- `Timex.Ecto.DateTime`: An ISO 8601 datetime in UTC\n- `Timex.Ecto.DateTimeWithTimezone`: Same as DateTime, but contains the timezone, i.e. `America/Chicago` as well. **NOTE** currently this is only supported with PostgreSQL, as it relies on complex types which are not currently supported in MySQL, and SQL Server user defined types require CLR types backing them which I have not explored in depth as of yet. See the section below titled [Using DateTimeWithTimezone](doc:using-with-ecto#section-using-datetimewithtimezone) for details.\n\n### Model Definition\n\nIn order to use the Timex DateTime type instead of the Ecto DateTime type, your model should look something like the following:\n\n```elixir\ndefmodule User do\n  use Ecto.Model\n\n  schema \"users\" do\n    field :name, :string\n    field :a_date,       Timex.Ecto.Date # Timex version of :date\n    field :a_time,       Timex.Ecto.Time # Timex version of :time\n    field :a_datetime,   Timex.Ecto.DateTime # Timex version of :datetime\n    field :a_datetimetz, Timex.Ecto.DateTimeWithTimezone # A custom datatype (:datetimetz) implemented by Timex\n  end\nend\n```\n\n### Using Timex with Ecto's `timestamps` macro\n\nSuper simple! Your timestamps will now be `Timex.DateTime` structs instead of `Ecto.DateTime` structs.\n\n```elixir\ndefmodule User do\n  use Ecto.Model\n  use Timex.Ecto.Timestamps\n\n  schema \"users\" do\n    field :name, :string\n    timestamps\n  end\nend\n```\n\n### Using with Phoenix\n\nPhoenix allows you to apply defaults globally to Ecto models via `web/web.ex` by changing the `model` function like so:\n\n```elixir\ndef model do\n  quote do\n    use Ecto.Model\n    use Timex.Ecto.Timestamps\n  end\nend\n```\n\nBy doing this, you bring the Timex timestamps into scope in all your models.\n\n### Using DateTimeWithTimezone\n\nNOTE: This currently only applies to PostgreSQL.\n\nYou must run the following SQL against the database you plan on using this type with:\n\n```sql\nCREATE TYPE datetimetz AS (\n    dt timestamptz,\n    tz varchar\n);\n```\n\nYou can then use this type like so:\n\n```sql\nCREATE TABLE example (\n  id integer,\n  created_at datetimetz\n);\n```\n\nThat's it!\n\n### Full Example\n\nThe following is a simple test app I built for vetting this plugin:\n\n```elixir\ndefmodule EctoTest.Repo do\n  use Ecto.Repo, otp_app: :timex_ecto_test\nend\n\ndefmodule EctoTest.User do\n  use Ecto.Model\n  use Timex.Ecto.Timestamps\n\n  schema \"users\" do\n    field :name, :string\n    field :date_test,       Timex.Ecto.Date\n    field :time_test,       Timex.Ecto.Time\n    field :datetime_test,   Timex.Ecto.DateTime\n    field :datetimetz_test, Timex.Ecto.DateTimeWithTimezone\n  end\nend\n\ndefmodule EctoTest do\n  import Ecto.Query\n  use Timex\n\n  alias EctoTest.User\n  alias EctoTest.Repo\n\n  def seed do\n    time       = Time.now\n    datetime   = Date.now\n    datetimetz = Timezone.convert(datetime, \"Europe/Copenhagen\")\n    u = %User{name: \"Paul\", date_test: datetime, time_test: time, datetime_test: datetime, datetimetz_test: datetimetz}\n    Repo.insert!(u)\n  end\n\n  def all do\n    query = from u in User,\n            select: u\n    Repo.all(query)\n  end\nend\n\ndefmodule EctoTest.App do\n  use Application\n\n  def start(_type, _args) do\n    import Supervisor.Spec\n    tree = [worker(EctoTest.Repo, [])]\n    opts = [name: EctoTest.Sup, strategy: :one_for_one]\n    Supervisor.start_link(tree, opts)\n  end\nend\n```\n\nAnd the results:\n\n```elixir\niex(1)> EctoTest.seed\n\n14:45:43.461 [debug] INSERT INTO \"users\" (\"date_test\", \"datetime_test\", \"datetimetz_test\", \"name\", \"time_test\") VALUES ($1, $2, $3, $4, $5) RETURNING \"id\" [{2015, 6, 25}, {{2015, 6, 25}, {19, 45, 43, 457000}}, {{{2015, 6, 25}, {21, 45, 43, 457000}}, \"Europe/Copenhagen\"}, \"Paul\", {19, 45, 43, 457000}] OK query=3.9ms\n%EctoTest.User{__meta__: %Ecto.Schema.Metadata{source: \"users\",\n  state: :loaded},\n date_test: %Timex.DateTime{calendar: :gregorian, day: 25, hour: 19, minute: 45,\n  month: 6, ms: 457, second: 43,\n  timezone: %Timex.TimezoneInfo{abbreviation: \"UTC\", from: :min,\n   full_name: \"UTC\", offset_std: 0, offset_utc: 0, until: :max}, year: 2015},\n datetime_test: %Timex.DateTime{calendar: :gregorian, day: 25, hour: 19,\n  minute: 45, month: 6, ms: 457, second: 43,\n  timezone: %Timex.TimezoneInfo{abbreviation: \"UTC\", from: :min,\n   full_name: \"UTC\", offset_std: 0, offset_utc: 0, until: :max}, year: 2015},\n datetimetz_test: %Timex.DateTime{calendar: :gregorian, day: 25, hour: 21,\n  minute: 45, month: 6, ms: 457, second: 43,\n  timezone: %Timex.TimezoneInfo{abbreviation: \"CEST\",\n   from: {:sunday, {{2015, 3, 29}, {2, 0, 0}}}, full_name: \"Europe/Copenhagen\",\n   offset_std: 60, offset_utc: 60,\n   until: {:sunday, {{2015, 10, 25}, {2, 0, 0}}}}, year: 2015}, id: nil,\n name: \"Paul\", time_test: {1435, 261543, 456856}}\niex(2)> EctoTest.all\n\n14:45:46.721 [debug] SELECT u0.\"id\", u0.\"name\", u0.\"date_test\", u0.\"time_test\", u0.\"datetime_test\", u0.\"datetimetz_test\" FROM \"users\" AS u0 [] OK query=0.7ms\n[%EctoTest.User{__meta__: %Ecto.Schema.Metadata{source: \"users\",\n   state: :loaded},\n  date_test: %Timex.DateTime{calendar: :gregorian, day: 25, hour: 0, minute: 0,\n   month: 6, ms: 0, second: 0,\n   timezone: %Timex.TimezoneInfo{abbreviation: \"UTC\", from: :min,\n    full_name: \"UTC\", offset_std: 0, offset_utc: 0, until: :max}, year: 2015},\n  datetime_test: %Timex.DateTime{calendar: :gregorian, day: 25, hour: 19,\n   minute: 45, month: 6, ms: 457.0, second: 43,\n   timezone: %Timex.TimezoneInfo{abbreviation: \"UTC\", from: :min,\n    full_name: \"UTC\", offset_std: 0, offset_utc: 0, until: :max}, year: 2015},\n  datetimetz_test: %Timex.DateTime{calendar: :gregorian, day: 25, hour: 21,\n   minute: 45, month: 6, ms: 457.0, second: 43,\n   timezone: %Timex.TimezoneInfo{abbreviation: \"CEST\",\n    from: {:sunday, {{2015, 3, 29}, {2, 0, 0}}}, full_name: \"Europe/Copenhagen\",\n    offset_std: 60, offset_utc: 60,\n    until: {:sunday, {{2015, 10, 25}, {2, 0, 0}}}}, year: 2015}, id: nil,\n  name: \"Paul\", time_test: {0, 71143, 0}}]\niex(3)>\n```\n\nAnd that's all there is to it!","excerpt":"How to use Timex DateTimes with Ecto","slug":"using-with-ecto","type":"basic","title":"Using with Ecto"}

Using with Ecto

How to use Timex DateTimes with Ecto

### Getting Started Timex has can be integrated with Ecto via the `timex_ecto` plugin which is available on hex.pm: ```elixir defp deps do [{:timex, "~> x.x.x"}, {:timex_ecto, "~> x.x.x"}] end ``` ### Available Types Timex-Ecto exposes a few different types for you to use: - `Timex.Ecto.Date`: An ISO date (`YYYY-MM-DD`) - `Timex.Ecto.Time`: An ISO time (`hh:mm:ss.sss`) - `Timex.Ecto.DateTime`: An ISO 8601 datetime in UTC - `Timex.Ecto.DateTimeWithTimezone`: Same as DateTime, but contains the timezone, i.e. `America/Chicago` as well. **NOTE** currently this is only supported with PostgreSQL, as it relies on complex types which are not currently supported in MySQL, and SQL Server user defined types require CLR types backing them which I have not explored in depth as of yet. See the section below titled [Using DateTimeWithTimezone](doc:using-with-ecto#section-using-datetimewithtimezone) for details. ### Model Definition In order to use the Timex DateTime type instead of the Ecto DateTime type, your model should look something like the following: ```elixir defmodule User do use Ecto.Model schema "users" do field :name, :string field :a_date, Timex.Ecto.Date # Timex version of :date field :a_time, Timex.Ecto.Time # Timex version of :time field :a_datetime, Timex.Ecto.DateTime # Timex version of :datetime field :a_datetimetz, Timex.Ecto.DateTimeWithTimezone # A custom datatype (:datetimetz) implemented by Timex end end ``` ### Using Timex with Ecto's `timestamps` macro Super simple! Your timestamps will now be `Timex.DateTime` structs instead of `Ecto.DateTime` structs. ```elixir defmodule User do use Ecto.Model use Timex.Ecto.Timestamps schema "users" do field :name, :string timestamps end end ``` ### Using with Phoenix Phoenix allows you to apply defaults globally to Ecto models via `web/web.ex` by changing the `model` function like so: ```elixir def model do quote do use Ecto.Model use Timex.Ecto.Timestamps end end ``` By doing this, you bring the Timex timestamps into scope in all your models. ### Using DateTimeWithTimezone NOTE: This currently only applies to PostgreSQL. You must run the following SQL against the database you plan on using this type with: ```sql CREATE TYPE datetimetz AS ( dt timestamptz, tz varchar ); ``` You can then use this type like so: ```sql CREATE TABLE example ( id integer, created_at datetimetz ); ``` That's it! ### Full Example The following is a simple test app I built for vetting this plugin: ```elixir defmodule EctoTest.Repo do use Ecto.Repo, otp_app: :timex_ecto_test end defmodule EctoTest.User do use Ecto.Model use Timex.Ecto.Timestamps schema "users" do field :name, :string field :date_test, Timex.Ecto.Date field :time_test, Timex.Ecto.Time field :datetime_test, Timex.Ecto.DateTime field :datetimetz_test, Timex.Ecto.DateTimeWithTimezone end end defmodule EctoTest do import Ecto.Query use Timex alias EctoTest.User alias EctoTest.Repo def seed do time = Time.now datetime = Date.now datetimetz = Timezone.convert(datetime, "Europe/Copenhagen") u = %User{name: "Paul", date_test: datetime, time_test: time, datetime_test: datetime, datetimetz_test: datetimetz} Repo.insert!(u) end def all do query = from u in User, select: u Repo.all(query) end end defmodule EctoTest.App do use Application def start(_type, _args) do import Supervisor.Spec tree = [worker(EctoTest.Repo, [])] opts = [name: EctoTest.Sup, strategy: :one_for_one] Supervisor.start_link(tree, opts) end end ``` And the results: ```elixir iex(1)> EctoTest.seed 14:45:43.461 [debug] INSERT INTO "users" ("date_test", "datetime_test", "datetimetz_test", "name", "time_test") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [{2015, 6, 25}, {{2015, 6, 25}, {19, 45, 43, 457000}}, {{{2015, 6, 25}, {21, 45, 43, 457000}}, "Europe/Copenhagen"}, "Paul", {19, 45, 43, 457000}] OK query=3.9ms %EctoTest.User{__meta__: %Ecto.Schema.Metadata{source: "users", state: :loaded}, date_test: %Timex.DateTime{calendar: :gregorian, day: 25, hour: 19, minute: 45, month: 6, ms: 457, second: 43, timezone: %Timex.TimezoneInfo{abbreviation: "UTC", from: :min, full_name: "UTC", offset_std: 0, offset_utc: 0, until: :max}, year: 2015}, datetime_test: %Timex.DateTime{calendar: :gregorian, day: 25, hour: 19, minute: 45, month: 6, ms: 457, second: 43, timezone: %Timex.TimezoneInfo{abbreviation: "UTC", from: :min, full_name: "UTC", offset_std: 0, offset_utc: 0, until: :max}, year: 2015}, datetimetz_test: %Timex.DateTime{calendar: :gregorian, day: 25, hour: 21, minute: 45, month: 6, ms: 457, second: 43, timezone: %Timex.TimezoneInfo{abbreviation: "CEST", from: {:sunday, {{2015, 3, 29}, {2, 0, 0}}}, full_name: "Europe/Copenhagen", offset_std: 60, offset_utc: 60, until: {:sunday, {{2015, 10, 25}, {2, 0, 0}}}}, year: 2015}, id: nil, name: "Paul", time_test: {1435, 261543, 456856}} iex(2)> EctoTest.all 14:45:46.721 [debug] SELECT u0."id", u0."name", u0."date_test", u0."time_test", u0."datetime_test", u0."datetimetz_test" FROM "users" AS u0 [] OK query=0.7ms [%EctoTest.User{__meta__: %Ecto.Schema.Metadata{source: "users", state: :loaded}, date_test: %Timex.DateTime{calendar: :gregorian, day: 25, hour: 0, minute: 0, month: 6, ms: 0, second: 0, timezone: %Timex.TimezoneInfo{abbreviation: "UTC", from: :min, full_name: "UTC", offset_std: 0, offset_utc: 0, until: :max}, year: 2015}, datetime_test: %Timex.DateTime{calendar: :gregorian, day: 25, hour: 19, minute: 45, month: 6, ms: 457.0, second: 43, timezone: %Timex.TimezoneInfo{abbreviation: "UTC", from: :min, full_name: "UTC", offset_std: 0, offset_utc: 0, until: :max}, year: 2015}, datetimetz_test: %Timex.DateTime{calendar: :gregorian, day: 25, hour: 21, minute: 45, month: 6, ms: 457.0, second: 43, timezone: %Timex.TimezoneInfo{abbreviation: "CEST", from: {:sunday, {{2015, 3, 29}, {2, 0, 0}}}, full_name: "Europe/Copenhagen", offset_std: 60, offset_utc: 60, until: {:sunday, {{2015, 10, 25}, {2, 0, 0}}}}, year: 2015}, id: nil, name: "Paul", time_test: {0, 71143, 0}}] iex(3)> ``` And that's all there is to it!