nresni
February 6, 2019, 5:08pm
1
Hi,
I try to retrieve the first and last day of previous month to build a query with a range date.
Right now I’m doing this:
def foo(%DateTime{month: month, year: year} = current_date) do
# eg. 2019-01-01 00:00:00
start_date = %{current_date | month: month - 1, day: 1, hour: 00, minute: 00, second: 00}
days_of_month = DateTime.to_date(start_date) |> Date.days_in_month()
# eg. 2019-01-31 23:59:59
end_date = DateTime.add(start_date, (days_of_month - 1) * 86_400 + 86_399, :seconds)
...
end
For the moment I don’t handle the year change , but before continuing I wanted to know if you had another way of doing it.
Thanks
Please don’t do such calculations on your own you’re bound to get into trouble with things like daylight-savings time switches or leap-seconds and things like that. Use a library like timex or calendar for calculations on datetimes.
7 Likes
nresni
February 6, 2019, 5:26pm
3
Oh yes, my bad, timex has everything I need.
Thanks
2 Likes
And when timex is not an option, one could use the API that comes with elixir to handle date a safer way too. Like DateTime.add
or DateTime.diff
for example.
To get the last day of previous month with bare Elixir for example:
datetime = DateTime.utc_now()
date = DateTime.to_date(datetime)
last_day_of_previous_month = Date.add(date, date.day * -1)
end_of_last_day_on_original_timezone = last_day_of_previous_month |> NaiveDateTime.new(~T[23:59:59]) |> DateTime.from_naive(datetime.time_zone)
rio517
March 30, 2023, 10:40am
6
Just in case someone stumbles across this, there are built-in functions to help with these calculations.
iex> Date.beginning_of_month(~D[2000-01-31])
~D[2000-01-01]
iex> Date.end_of_month(~D[2000-01-01])
~D[2000-01-31]
https://hexdocs.pm/elixir/Date.html#beginning_of_month/1
4 Likes