Elixir: How to sort a list of (naive) datetimes?

Viewed 1377

I have a list of NaiveDateTimes and I want to get the most recent one. What's the easiest way to sort a list of DateTimes / NaiveDateTimes?

I know it's unsafe to use Elixir's standard sorting rules, since it compares terms structurally rather than looking at the meaning of the dates:

# UNSAFE / returns entries in incorrect order:
[~N[2020-02-29 10:00:01], ~N[2020-03-11 10:20:00], ~N[2020-03-15 10:00:00]] |> Enum.sort
# => [~N[2020-03-11 10:20:00], ~N[2020-03-15 10:00:00], ~N[2020-02-29 10:00:01]]
2 Answers

Since v1.9 Enum.sort/2 accepts a module that exports compare/2.

Enum.sort(naive_date_times, NaiveDateTime)
Enum.sort(dates, Date)

If all values are DateTime (with timezone), you can use DateTime.compare:

sorted = Enum.sort(datetimes, & DateTime.compare(&1, &2) != :gt)

If all values are NaiveDateTime (no timezone data), you can use NaiveDateTime.compare:

sorted = Enum.sort(datetimes, & NaiveDateTime.compare(&1, &2) != :gt)

And if you're lazy and/or have Timex installed, you can use Timex.diff which will infer UTC timezone for any NaiveDateTimes:

sorted = Enum.sort(datetimes, & Timex.diff(&1, &2) < 0)
Related