How to get a difference between "now()" and another date and make sure it doesn't exceed N days?

I’m using Phoenix and Ecto. I need to check if a difference between “now()” and a certain date less than 3 days. Exactly I’m trying this:

    {diff_days, {_, _, _}} = Ecto.DateTime.to_erl(my_user.signed_up_at) |> :calendar.time_difference(:calendar.universal_time)
    if diff_days <= 3 do
      # good to go
      # ....
    end

However, this won’t for a date older than 3 days and 1 minute, right?

What’s the univeral way to check if it’s not more but 3 days or 72 hours?

In my database signed_up_at is of type timestamp without timezone

Hi,

In Elixir 1.5 you have DateTime.diff/3 and NaiveDateTime.diff/3. Otherwise I suggest one of the available libraries, either https://hex.pm/packages/calendar or https://hex.pm/packages/timex. Each includes a function to calculate the time diff in one or more time units.

This is not as simple as you might think… I’m remembering the discussions around the introduction of elixirs calender related stuff with 1.5.

In my opinion your options are to update elixir or to choose a library to do that calculation.

But I fear that most current versions of the time related libraries do already depend on 1.5 as it uniforms how times are represented in memory and therefore makes it much easier to interop.

If though you insist on not updating you can take a look at erlangs calendar module. It has at least one Time-Dorf function,which is deprecated though…

If you want use just :calendar without libraries, you can just do it simpy this way:

defmodule DateHelperTest do
  use ExUnit.Case

  test "date is not older than 3 days" do
    assert DateHelper.not_older_than?({{2018, 1, 9}, {}}, 3)
    assert DateHelper.not_older_than?({{2018, 1, 15}, {}}, 3)
    refute DateHelper.not_older_than?({{2016, 1, 9}, {}}, 3)
    refute DateHelper.not_older_than?({{2018, 1, 7}, {}}, 3)
    refute DateHelper.not_older_than?({{2018, 1, 8}, {}}, 3)
  end
end

defmodule DateHelper do
  def not_older_than?(date, days) do
    diff_days(extract_date(:calendar.universal_time), extract_date(date)) <= days
  end

  defp extract_date({date, _}), do: date

  defp diff_days(d1, d2) do
    :calendar.date_to_gregorian_days(d1) - :calendar.date_to_gregorian_days(d2)
  end
end

# and your code:
if DateHelper.not_older_than?(Ecto.DateTime.to_erl(my_user.signed_up_at), 3) do
 # good to go
1 Like

So maybe it would be enough to compare the number of seconds between now and the date in the past?

iex(8)> DateTime.to_unix(DateTime.utc_now()) -  DateTime.to_unix(DateTime.from_naive!(~N[2018-01-05 13:26:08.003], "Etc/UTC"))
591992

I flagged your comment because you were using very inflammatory language without any provocation or reason, precisely as you are doing in this one. Please try to be less vitriolic in your language on the forum. There is no reason to be using terms like “idiot” or saying people would be mentally deficient or whatever if they do things differently than you.

4 Likes