To Get Previous 30 days the Date in Elixir

learning-elixir
#1

How can i do this in Elixir?

I need to get previous 30 day the Date

Exp. Today 2019/09/12 and i need to get 2019/08/13

DateTime.utc_now - 30days

2 Likes
#2

If you have Elixir 1.8, use https://hexdocs.pm/elixir/DateTime.html#add/4 to add negative 30 days. You will need to install a timezone database such as https://hex.pm/packages/tzdata for it to work.

If you have some earlier Elixir version, you need to install Timex or lau/calendar and use that instead.

3 Likes
#3

Writing out what @Nicd pointed to:

iex(1)> seconds = - 30 * 24 * 3600 # minus 30 days, calculated as seconds
-2592000
iex(2)> {:ok, date} = DateTime.now("Etc/UTC")
{:ok, #DateTime<2019-05-15 09:10:28.998546Z>}
iex(3)> DateTime.add(date, seconds, :second)
#DateTime<2019-04-15 09:10:28.998546Z>```

Or resorting to Erlang’s calendar module

{year, month, day} 
  =  :erlang.date() 
  |> :calendar.date_to_gregorian_days() 
  |> Kernel.-(30) 
  |> :calendar.gregorian_days_to_date()
2 Likes
#4

you also have Date eg:

iex(1)> Date.utc_today |> Date.add(-30)
~D[2019-04-15]
6 Likes
#5

Hehe oh dear, I totally missed this and focused only on the word DateTime in the code example. This is of course the simplest solution if you only need a date (and not time).

3 Likes
#6

Doing calendar based operations by inferring the bygone seconds is almost never a good idea. E.g. you could be landing directly in a non-existing datetime where a certain timezone is moved an hour forward because of a DST switch. Given that in this case it’s just about dates and not datetimes it might be fine, but with the Date module having better options I’d still consider it bad practice.

3 Likes
#7

Good point on just using the Date module.

On non-existing dates: By using DateTime together with a timezone (“Etc/UTC”) this shouldn’z happen. What can happen is that the date calculated is incorrect depending on what a person means with “30 days before”.

  • I could be the same clock time just 30 days before
  • It could mean the full interval of 30 days (=> 30242600 seconds) be be sure it’s the same (comparable) time span.

On the latter: Of course, one should use a calendaring library like DateTime for this instead of manipulating epoch second

I guess @sen was looking for the former, so you are right in this regard. Just reminding of the latter use case you called bad practice.

1 Like