How to parse DateTime in Elixir?
Solution 1
To get the current date and or time, you can use one of
Ecto.Date.utc
Ecto.Time.utc
Ecto.DateTime.utc
DateTime.utc_now
As for converting a {DD, MM, YY}
tuple into an Ecto.Date
, you will not be able to do that with ecto provided functions. However, you can use a {YYYY, MM, DD}
tuple to convert into Ecto.Date
.
Ecto.Date.from_erl({2016, 12, 4})
#Ecto.Date<2016-12-04>
Date.from_erl({2016, 12, 4})
{:ok, ~D[2016-12-04]}
Ecto.Time.from_erl({13, 55, 10})
#Ecto.Time<12:10:08>
Ecto.Time.from_erl({13, 55, 10})
{:ok, ~T[13:55:10]}
Ecto.DateTime.from_erl({{2016, 12, 4}, {13, 55, 10}})
#Ecto.DateTime<2016-12-04 13:55:10>
Ecto.Date.from_erl({2016, 12, 4}) |> Ecto.DateTime.from_date()
#Ecto.Date<2016-12-04>
You just need to make sure your data is in the proper order these functions expect them to be.
As for parsing these from a string, you are either going to need to bring in another library, or write a parser yourself.
Solution 2
Just adding to the answer given by Justin. Elixir's standard library can parse ISO 8601 dates.
iex> Date.from_iso8601("2015-01-23")
{:ok, ~D[2015-01-23]}
or with the bang-version, that might raise errors:
iex> Date.from_iso8601!("2015-01-23")
~D[2015-01-23]
If you want a full datetime from an ISO 8601 string, you'll have to be satisfied with a NaiveDateTime, since there's no reliable time zone information to go on.
iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07")
{:ok, ~N[2015-01-23 23:50:07]}
Beware, it will simply throw away time zone offsets.
There is going to be a from_iso8601/1
on DateTime in the future, but it was recently added and has not been released as of Elixir v1.3.4. It will preserve time zone offset, but set the time zone to UTC.
Solution 3
As Martin Svalin and Erik Vullings already commented here, you can now parse strings to DateTime
in pure Elixir:
iex(5)> {:ok, date_time, offset} = DateTime.from_iso8601("2018-03-17 21:23:12+0100")
{:ok, #DateTime<2018-03-17 20:23:12Z>, 3600}
As you can see, I set an offset of +1 hour in my string. It was parsed correctly, but a DateTime
object doesn't keep timezone information, and when I print it, it displays the correct date and time, but printed by default in UTC.
If you want to keep the original timezone information, that's stored as an offset in seconds in the third element of the tuple (offset
in my example above).
Kooooro
Updated on June 20, 2022Comments
-
Kooooro almost 2 years
How can I create (
Ecto.
)DateTime
out of a tuple{DD, MM, YY}
, or parse it from a string in Elixir? Should I useDateTime
from Erlang for that?I've googled but haven't found anything and there's nothing in the documentation about the matter, only about
DateTime
in general -- how to get the current date and time, for example.Note that I don't want to use a third-party library such as
Timex
. -
Erik Vullings over 6 yearsThis function,
from_iso8601/1
has been implemented in Elixir v1.5.1. -
Ashish Sharma over 3 yearsHow can I print date in string format and not in ~D[some-date] ?
-
Martin Svalin over 3 yearsElixir 1.11 added a Calendar.strftime/3 function that will cover most datetime related printing needs, but the simplest way is to pass the date to Date.to_string/1. This will return the date formatted according to its calendar, so for a date in Calendar.ISO, that would be yyyy-mm-dd.