Skip to content

Instantly share code, notes, and snippets.

@somoza
Created November 26, 2023 00:36
Show Gist options
  • Save somoza/5b9a91f509b33c9643360e0c6550660a to your computer and use it in GitHub Desktop.
Save somoza/5b9a91f509b33c9643360e0c6550660a to your computer and use it in GitHub Desktop.
Calculate how many business days are for an option in the market taking in mind T+2 formula
defmodule Module.DateUtils do
@doc """
Functions to help with dates.
"""
@holidays [
# New year
~D[2023-01-01],
# Christmas
~D[2023-12-25]
]
@spec business_days_from_today(integer) :: {Date.t(), Integer.t()}
def business_days_from_today(count) when is_integer(count) do
today_in_local_timezone()
|> calculate_business_days(count, 0)
end
def today_in_local_timezone do
timezone_offset_hours = -3
DateTime.utc_now()
|> DateTime.add(timezone_offset_hours * 3600)
|> DateTime.to_date()
end
defp calculate_business_days(date, 0, acc), do: {date, acc}
defp calculate_business_days(date, count, acc) do
next_day = Date.add(date, 1)
is_business_day?(next_day)
|> maybe_add_day(next_day, count, acc)
end
defp is_business_day?(date) do
date
|> Date.day_of_week()
|> is_weekday?() and
date not in @holidays
end
defp is_weekday?(day_of_week) when day_of_week in 1..5, do: true
defp is_weekday?(_), do: false
defp maybe_add_day(true, next_day, count, acc),
do: calculate_business_days(next_day, count - 1, acc + 1)
defp maybe_add_day(false, next_day, count, acc),
do: calculate_business_days(next_day, count, acc + 1)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment