Format date with Elixir
Asked Answered
I

7

11

I'm trying to format the Timex module to look a certain way. I'm trying to get today's date. but I want it formatted like this:

2017/12/12.

year/mn/day

In ruby I would go to the strftime class but I'm not sure how to do this with Elixir:

Current attempt:

Timex.local => #DateTime<2017-12-12 19:57:17.232916-05:00 EST America/Detroit>

How can I take that and format it how I specified?

Immaterialism answered 13/12, 2017 at 1:0 Comment(1)
You can use PyyyymmddThhmmssfff and then replace - with /Bael
L
14

Timex is a third-party library that was created in the era when Elixir had no good support for dates/times. Nowadays, there is DateTime native class in the core, so I am unsure why do you want to use Timex at all.

In any case, DateTime is a struct:

iex|1 ▶ today = DateTime.utc_now
#⇒ #DateTime<2017-12-13 07:22:58.290075Z>
iex|2 ▶ [today.year, today.month, today.day]
#⇒ [2017, 12, 13]
iex|3 ▶ Enum.join [today.year, today.month, today.day], "/"
#⇒ "2017/12/13"

To pad with leading zeroes for "2018/1/1":

iex|4 ▶ with {:ok, today} <- Date.new(2018, 1, 1) do
...|4 ▶   [today.year, today.month, today.day]
...|4 ▶   |> Enum.map(&to_string/1)
...|4 ▶   |> Enum.map(&String.pad_leading(&1, 2, "0"))
...|4 ▶   |> Enum.join("/")
...|4 ▶ end
#⇒ "2018/01/01"
Letters answered 13/12, 2017 at 7:24 Comment(2)
I think, basically, still people want to use Timex if they need to do formatting, which Elixir still doesn't have any good way to do that I can see.Buckjumper
The Kalends package seems to offer some of the more traditional formatting codes: hexdocs.pm/kalendsBanded
A
28

Elixir 1.11 has Calendar.strftime/3 built-in for your strftime needs.

Calendar.strftime(~U[2019-08-26 13:52:06.0Z], "%y-%m-%d %I:%M:%S %p")
"19-08-26 01:52:06 PM"
Alfilaria answered 21/3, 2021 at 0:45 Comment(1)
link is broken, here is the latest: hexdocs.pm/elixir/1.16.1/Calendar.html#strftime/3Moxley
L
14

Timex is a third-party library that was created in the era when Elixir had no good support for dates/times. Nowadays, there is DateTime native class in the core, so I am unsure why do you want to use Timex at all.

In any case, DateTime is a struct:

iex|1 ▶ today = DateTime.utc_now
#⇒ #DateTime<2017-12-13 07:22:58.290075Z>
iex|2 ▶ [today.year, today.month, today.day]
#⇒ [2017, 12, 13]
iex|3 ▶ Enum.join [today.year, today.month, today.day], "/"
#⇒ "2017/12/13"

To pad with leading zeroes for "2018/1/1":

iex|4 ▶ with {:ok, today} <- Date.new(2018, 1, 1) do
...|4 ▶   [today.year, today.month, today.day]
...|4 ▶   |> Enum.map(&to_string/1)
...|4 ▶   |> Enum.map(&String.pad_leading(&1, 2, "0"))
...|4 ▶   |> Enum.join("/")
...|4 ▶ end
#⇒ "2018/01/01"
Letters answered 13/12, 2017 at 7:24 Comment(2)
I think, basically, still people want to use Timex if they need to do formatting, which Elixir still doesn't have any good way to do that I can see.Buckjumper
The Kalends package seems to offer some of the more traditional formatting codes: hexdocs.pm/kalendsBanded
T
9

If you want to do this without an external library, you can use io_lib:format/2 to pad the integers with zeroes where necessary like this:

iex(1)> date = Date.utc_today
~D[2017-12-13]
iex(2)> :io_lib.format("~4..0B/~2..0B/~2..0B", [date.year, date.month, date.day]) |> IO.iodata_to_binary
"2017/12/13"
iex(3)> {:ok, date} = Date.new(2018, 1, 1)
{:ok, ~D[2018-01-01]}
iex(4)> :io_lib.format("~4..0B/~2..0B/~2..0B", [date.year, date.month, date.day]) |> IO.iodata_to_binary
"2018/01/01"
iex(5)> {:ok, date} = Date.new(1, 1, 1)
{:ok, ~D[0001-01-01]}
iex(6)> :io_lib.format("~4..0B/~2..0B/~2..0B", [date.year, date.month, date.day]) |> IO.iodata_to_binary
"0001/01/01"
Twosome answered 13/12, 2017 at 11:30 Comment(0)
K
7

You can do this to add zeros

Timex.local |>  Timex.format!("{YYYY}/0{M}/0{D}") => "2017/01/01"
Kleon answered 30/7, 2018 at 13:6 Comment(1)
Your format string doesn't quite produce the result it should. Use this instead: Timex.format!("{YYYY}/{0M}/{0D}")Pint
I
4

So it appears the Timex Module has a format!/2 function which will return a string of what ever date you pass to it.

Here is what I came up with: Timex.local |> Timex.format!("{YYYY}/{M}/{D}") => "2017/12/12"

Immaterialism answered 13/12, 2017 at 1:12 Comment(0)
Z
2

As of Elixir 1.11 you can do this sanely with a date formatter in the standard library's Calendar module:

https://hexdocs.pm/elixir/1.13.0/Calendar.html#strftime/3

DateTime.utc_now()
|> Calendar.strftime("%Y/%m/%d")

"2022/01/12"

Zelda answered 12/1, 2022 at 23:54 Comment(0)
V
1

The answer to add 0 padding is incorrect and will always pad 0s even if it does not require it. The correct way to pad 0s is as follows:

Timex.local |>  Timex.format!("{YYYY}/{0M}/{0D}") => "2017/01/01"
Voltage answered 7/12, 2020 at 20:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.