diff --git a/holiday/.formatter.exs b/holiday/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/holiday/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/holiday/.gitignore b/holiday/.gitignore new file mode 100644 index 0000000..89b042c --- /dev/null +++ b/holiday/.gitignore @@ -0,0 +1,26 @@ +# The directory Mix will write compiled artifacts to. +/_build/ + +# If you run "mix test --cover", coverage assets end up here. +/cover/ + +# The directory Mix downloads your dependencies sources to. +/deps/ + +# Where third-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch + +# If the VM crashes, it generates a dump, let's ignore it too. +erl_crash.dump + +# Also ignore archive artifacts (built via "mix archive.build"). +*.ez + +# Ignore package tarball (built via "mix hex.build"). +holiday-*.tar + +# Temporary files, for example, from tests. +/tmp/ diff --git a/holiday/README.md b/holiday/README.md new file mode 100644 index 0000000..c71d098 --- /dev/null +++ b/holiday/README.md @@ -0,0 +1,24 @@ +# Holiday + +**TODO: Add description** + +## Installation + +If [available in Hex](https://hex.pm/docs/publish), the package can be installed +by adding `holiday` to your list of dependencies in `mix.exs`: + +```elixir +def deps do + [ + {:holiday, "~> 0.1.0"} + ] +end +``` + +## Coomands +`rm _build/ -r && mix compile` + +Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) +and published on [HexDocs](https://hexdocs.pm). Once published, the docs can +be found at . + diff --git a/holiday/config/config.exs b/holiday/config/config.exs new file mode 100644 index 0000000..c48c3ed --- /dev/null +++ b/holiday/config/config.exs @@ -0,0 +1,8 @@ +import Config +config :holiday, ecto_repos: [Holiday.Repo] + +config :holiday, Holiday.Repo, + database: "holiday_repo", + username: "postgres", + password: "", + hostname: "localhost" diff --git a/holiday/lib/holiday.ex b/holiday/lib/holiday.ex new file mode 100644 index 0000000..9d63631 --- /dev/null +++ b/holiday/lib/holiday.ex @@ -0,0 +1,170 @@ +defmodule Holiday do + import Ecto.Query + alias Holiday.{Repo, Event} + + @moduledoc """ + Documentation for `Holiday`. + """ + + @doc """ + Initializing the local database. + + """ + @spec init_db() :: [] + def init_db() do + path = Path.expand("lib/us-california-nonworkingdays.ics") + + {:ok, binary} = File.read(path) + + Enum.each(binary |> ICalendar.from_ics(), fn event -> + + result = + case Repo.get_by(Event, uid: event.uid) do + nil -> %Event{uid: event.uid} + myEvent -> myEvent + end + |> Ecto.Changeset.change(%{ + uid: event.uid, + title: event.summary, + dStart: %{DateTime.to_date(event.dtstart) | year: 1970}, + dEnd: %{DateTime.to_date(event.dtend) | year: 1970}, + rules: event.rrule, + isConfirmed: event.status == "confirmed" + }) + |> Holiday.Repo.insert_or_update() + + case result do + {:ok, struct} -> + {:ok, struct} + + {:error, changeset} -> + {:error, changeset} + end + end) + + true + end + + @doc """ + Returns true if today is a holiday, and false it it's not.. + + ## Parameters + + - day: Date that represents the default is today's date or a user-specified date. + + ## Examples + + iex> Holiday.is_holiday(~D[2000-01-01]) + true + + """ + @spec is_holiday(day :: %Date{}) :: boolean() + def is_holiday(day \\ Date.utc_today()) do + Repo.exists?(from(e in Event, where: e.dStart == ^make_start_date(day))) + end + + defp getOneEvent(day, recursion \\ true) do + result = + Repo.one( + from( + e in Event, + where: e.dStart > ^day, + order_by: [asc: e.dStart], + limit: 1 + ) + ) + + unless result do + if recursion && getOneEvent(make_start_date(day, 1969), false), do: true, else: false + end + + result + end + + @doc """ + Return a float representing a number of `units till closest holiday in the future. + + ## Parameters + + - unit: Atom. Can be one of :day | :hour | :minute | :second + - now: Date that represents the default is today's date or a user-specified date. + + ## Examples + + iex> Holiday.time_until_holiday(:day, ~U[2022-01-12 00:01:00.00Z]) + 19.999305555555555 + + iex> Holiday.time_until_holiday(:hour, ~U[2022-01-12 00:01:00.00Z]) + 479.98333333333335 + + """ + @spec time_until_holiday( + unit :: :day | :hour | :minute | :second, + now :: %DateTime{} + ) :: float() + def time_until_holiday(unit, now \\ DateTime.utc_now()) + + def time_until_holiday(:day, now) do + find_nearest(now) / 60 / 60 / 24 + end + + def time_until_holiday(:hour, now) do + find_nearest(now) / 60 / 60 + end + + def time_until_holiday(:minute, now) do + find_nearest(now) / 60 + end + + def time_until_holiday(:second, now) do + find_nearest(now) + end + + @doc """ + Displays all holidays in the database in the format: Holiday Name: Start Date - End Date. + + + ## Examples + + iex> Holiday.show_all_events() + true + + """ + @spec show_all_events() :: [] + def show_all_events() do + query = from(e in Event) + + db = Repo.all(query) + + for event <- db do + IO.puts("#{event.title}: #{event.dStart} - #{event.dEnd}") + event + end + + true + end + + defp make_start_date(date, year \\ 1970) do + Date.new(year, date.month, date.day) |> elem(1) + end + + defp make_fake_date_time(%Date{} = date) do + time = Time.new(0, 0, 0, 0) |> elem(1) + + DateTime.new(date, time) + |> elem(1) + end + + defp make_fake_date_time(%DateTime{} = date) do + %{date | year: 1970} + end + + defp find_nearest(date) do + new_date = date |> make_fake_date_time + + getOneEvent(DateTime.to_date(new_date) |> make_start_date()).dStart + |> make_start_date + |> make_fake_date_time + |> DateTime.diff(new_date) + end +end diff --git a/holiday/lib/holiday/application.ex b/holiday/lib/holiday/application.ex new file mode 100644 index 0000000..23ba09c --- /dev/null +++ b/holiday/lib/holiday/application.ex @@ -0,0 +1,25 @@ +defmodule Holiday.Application do + # See https://hexdocs.pm/elixir/Application.html + # for more information on OTP Applications + @moduledoc false + use Application + + @impl true + def start(_type, _args) do + children = [ + Holiday.Repo + # Starts a worker by calling: Friends.Worker.start_link(arg) + # {Friends.Worker, arg} + ] + + # See https://hexdocs.pm/elixir/Supervisor.html + # for other strategies and supported options + opts = [strategy: :one_for_one, name: Holiday.Supervisor] + Supervisor.start_link(children, opts) + end + + def init(_type, config) do + IO.puts("STARTING REPO") + {:ok, config} + end +end diff --git a/holiday/lib/holiday/holiday.ex b/holiday/lib/holiday/holiday.ex new file mode 100644 index 0000000..6caf06c --- /dev/null +++ b/holiday/lib/holiday/holiday.ex @@ -0,0 +1,12 @@ +defmodule Holiday.Event do + use Ecto.Schema + + schema "holiday" do + field(:title, :string) + field(:dStart, :date) + field(:dEnd, :date) + field(:uid, :binary_id) + field(:rules, :map) + field(:isConfirmed, :boolean) + end +end diff --git a/holiday/lib/holiday/repo.ex b/holiday/lib/holiday/repo.ex new file mode 100644 index 0000000..6cc3d76 --- /dev/null +++ b/holiday/lib/holiday/repo.ex @@ -0,0 +1,5 @@ +defmodule Holiday.Repo do + use Ecto.Repo, + otp_app: :holiday, + adapter: Ecto.Adapters.Postgres +end diff --git a/holiday/lib/mix/tasks/init_db.ex b/holiday/lib/mix/tasks/init_db.ex new file mode 100644 index 0000000..4d4e833 --- /dev/null +++ b/holiday/lib/mix/tasks/init_db.ex @@ -0,0 +1,13 @@ +defmodule Mix.Tasks.InitDb do + use Mix.Task + + @shortdoc "Seed database." + def run(_) do + {:ok, _} = Application.ensure_all_started(:holiday) + + case Holiday.init_db() do + true -> IO.puts("Completed") + _ -> IO.puts("Error") + end + end +end diff --git a/holiday/lib/mix/tasks/is_holiday.ex b/holiday/lib/mix/tasks/is_holiday.ex new file mode 100644 index 0000000..3fd65f1 --- /dev/null +++ b/holiday/lib/mix/tasks/is_holiday.ex @@ -0,0 +1,13 @@ +defmodule Mix.Tasks.IsHoliday do + use Mix.Task + + @shortdoc "Returns Yes if today is a holiday, and No it it's not." + def run(_) do + {:ok, _} = Application.ensure_all_started(:holiday) + + case Holiday.is_holiday() do + true -> IO.puts("Yes") + _ -> IO.puts("No") + end + end +end diff --git a/holiday/lib/us-california-nonworkingdays.ics b/holiday/lib/us-california-nonworkingdays.ics new file mode 100644 index 0000000..09ac4b3 --- /dev/null +++ b/holiday/lib/us-california-nonworkingdays.ics @@ -0,0 +1,204 @@ +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Tri Tech Computers//node-icalendar//EN +X-WR-TIMEZONE:UTC +X-WR-CALNAME:California legal holidays +BEGIN:VEVENT +DTSTART;VALUE=DATE:19700101 +DTEND;VALUE=DATE:19700102 +RRULE:FREQ=YEARLY +UID:b901ca08-d924-43c3-9166-1d215c9453d6 +CLASS:PUBLIC +CREATED:20140109T004756Z +DESCRIPTION: +SEQUENCE:0 +STATUS:CONFIRMED +TRANSP:TRANSPARENT +SUMMARY:New Year's Day +DTSTAMP:20200425T153822Z +LAST-MODIFIED:20200425T153822Z +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:19830101 +DTEND;VALUE=DATE:19830102 +RRULE:FREQ=YEARLY;BYDAY=3MO +UID:0ae8128a-e360-492c-b2bd-52ed0d6d06fd +CLASS:PUBLIC +CREATED:20140109T004756Z +DESCRIPTION: +SEQUENCE:0 +STATUS:CONFIRMED +TRANSP:TRANSPARENT +SUMMARY:Marthin Luther King day/Robert E. Lee day +DTSTAMP:20200425T153822Z +LAST-MODIFIED:20200425T153822Z +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:19700201 +DTEND;VALUE=DATE:19700201 +RRULE:FREQ=YEARLY;BYDAY=3MO +UID:17425d41-9ed3-4088-adad-4693d1bd44c9 +CLASS:PUBLIC +CREATED:20140109T004756Z +DESCRIPTION: +CATEGORIES:-New Mexico +SEQUENCE:0 +STATUS:CONFIRMED +TRANSP:TRANSPARENT +SUMMARY:Presidents Day +DTSTAMP:20200425T153822Z +LAST-MODIFIED:20200425T153822Z +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:19700301 +DTEND;VALUE=DATE:19700302 +RRULE:FREQ=YEARLY;BYDAY=-1MO +UID:b4f8f9dc-28be-4e98-b45a-90230858da57 +CLASS:PUBLIC +CREATED:20140109T004756Z +DESCRIPTION: +CATEGORIES:Alaska,California +SEQUENCE:0 +STATUS:CONFIRMED +TRANSP:TRANSPARENT +SUMMARY:Seward Day +DTSTAMP:20200425T153822Z +LAST-MODIFIED:20200425T153822Z +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:19700501 +DTEND;VALUE=DATE:19700502 +RRULE:FREQ=YEARLY;BYDAY=-1MO +UID:4b714d32-c439-4acc-b7e4-fa6438ac4e39 +CLASS:PUBLIC +CREATED:20140109T004756Z +DESCRIPTION: +SEQUENCE:0 +STATUS:CONFIRMED +TRANSP:TRANSPARENT +SUMMARY:Memorial Day +DTSTAMP:20200425T153822Z +LAST-MODIFIED:20200425T153822Z +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:19700601 +DTEND;VALUE=DATE:19700602 +RRULE:FREQ=YEARLY;BYDAY=1MO +UID:03640abe-fadf-422c-9694-b9d9ae4a3875 +CLASS:PUBLIC +CREATED:20140109T004756Z +DESCRIPTION: +SEQUENCE:0 +STATUS:CONFIRMED +TRANSP:TRANSPARENT +SUMMARY:Jefferson Davis birthday +DTSTAMP:20200425T153822Z +LAST-MODIFIED:20200425T153822Z +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:19700704 +DTEND;VALUE=DATE:19700705 +RRULE:FREQ=YEARLY +UID:5a8d00d5-f08d-4117-8442-f55e95e57c98 +CLASS:PUBLIC +CREATED:20140109T004756Z +DESCRIPTION: +SEQUENCE:0 +STATUS:CONFIRMED +TRANSP:TRANSPARENT +SUMMARY:Independence Day +DTSTAMP:20200425T153822Z +LAST-MODIFIED:20200425T153822Z +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:19700724 +DTEND;VALUE=DATE:19700725 +RRULE:FREQ=YEARLY +UID:e53f9450-ca99-42ed-8be9-4dc2028fac62 +CLASS:PUBLIC +CREATED:20140109T004756Z +DESCRIPTION: +SEQUENCE:0 +STATUS:CONFIRMED +TRANSP:TRANSPARENT +SUMMARY:Pioneer Day +DTSTAMP:20200425T153822Z +LAST-MODIFIED:20200425T153822Z +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:19700901 +DTEND;VALUE=DATE:19700902 +RRULE:FREQ=YEARLY;BYDAY=1MO +UID:9c046886-5421-4562-ad2c-6045f1996ccf +CLASS:PUBLIC +CREATED:20140109T004756Z +DESCRIPTION: +SEQUENCE:0 +STATUS:CONFIRMED +TRANSP:TRANSPARENT +SUMMARY:Labor Day +DTSTAMP:20200425T153822Z +LAST-MODIFIED:20200425T153822Z +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:19701001 +DTEND;VALUE=DATE:19701002 +RRULE:FREQ=YEARLY;BYDAY=2MO +UID:e9e28671-b896-4a18-a509-61855edde3dd +CLASS:PUBLIC +CREATED:20140109T004756Z +DESCRIPTION: +CATEGORIES:-Alaska,-Hawaï,-Minnesota,-Nevada +SEQUENCE:0 +STATUS:CONFIRMED +TRANSP:TRANSPARENT +SUMMARY:Columbus Day +DTSTAMP:20200425T153822Z +LAST-MODIFIED:20200425T153822Z +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:19701111 +DTEND;VALUE=DATE:19701112 +RRULE:FREQ=YEARLY +UID:91634148-b2ee-4cc7-a6ec-ac943dd5aac8 +CLASS:PUBLIC +CREATED:20140109T004756Z +DESCRIPTION: +SEQUENCE:0 +STATUS:CONFIRMED +TRANSP:TRANSPARENT +SUMMARY:Veterans Day +DTSTAMP:20200425T153822Z +LAST-MODIFIED:20200425T153822Z +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:19701111 +DTEND;VALUE=DATE:19701112 +RRULE:FREQ=YEARLY;BYDAY=4TH +UID:8f3a60b1-f970-45e6-9cd0-83baa4d24977 +CLASS:PUBLIC +CREATED:20140109T004756Z +DESCRIPTION: +SEQUENCE:0 +STATUS:CONFIRMED +TRANSP:TRANSPARENT +SUMMARY:Thanksgiving Day +DTSTAMP:20200425T153822Z +LAST-MODIFIED:20200425T153822Z +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:19701225 +DTEND;VALUE=DATE:19701226 +RRULE:FREQ=YEARLY +UID:c1679873-ff26-4f96-a628-01e89a2049fb +CLASS:PUBLIC +CREATED:20140109T004755Z +DESCRIPTION: +SEQUENCE:0 +STATUS:CONFIRMED +TRANSP:TRANSPARENT +SUMMARY:Christmas +DTSTAMP:20200425T153822Z +LAST-MODIFIED:20200425T153822Z +END:VEVENT +END:VCALENDAR diff --git a/holiday/mix.exs b/holiday/mix.exs new file mode 100644 index 0000000..b239722 --- /dev/null +++ b/holiday/mix.exs @@ -0,0 +1,33 @@ +defmodule Holiday.MixProject do + use Mix.Project + + def project do + [ + app: :holiday, + version: "0.2.0", + elixir: "~> 1.13", + start_permanent: Mix.env() == :prod, + deps: deps() + ] + end + + # Run "mix help compile.app" to learn about applications. + def application do + [ + extra_applications: [:ecto, :postgrex, :logger], + mod: {Holiday.Application, []} + ] + end + + # Run "mix help deps" to learn about dependencies. + defp deps do + [ + {:ecto_sql, "~> 3.2"}, + {:postgrex, "~> 0.15"}, + {:jason, "~> 1.3"}, + {:icalendar, "~> 1.1.0"} + # {:dep_from_hexpm, "~> 0.3.0"}, + # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"} + ] + end +end diff --git a/holiday/mix.lock b/holiday/mix.lock new file mode 100644 index 0000000..440965d --- /dev/null +++ b/holiday/mix.lock @@ -0,0 +1,23 @@ +%{ + "certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"}, + "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"}, + "connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"}, + "db_connection": {:hex, :db_connection, "2.4.2", "f92e79aff2375299a16bcb069a14ee8615c3414863a6fef93156aee8e86c2ff3", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4fe53ca91b99f55ea249693a0229356a08f4d1a7931d8ffa79289b145fe83668"}, + "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, + "ecto": {:hex, :ecto, "3.9.0", "7c74fc0d950a700eb7019057ff32d047ed7f19b57c1b2ca260cf0e565829101d", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fed5ebc5831378b916afd0b5852a0c5bb3e7390665cc2b0ec8ab0c712495b73d"}, + "ecto_sql": {:hex, :ecto_sql, "3.9.0", "2bb21210a2a13317e098a420a8c1cc58b0c3421ab8e3acfa96417dab7817918c", [:mix], [{:db_connection, "~> 2.5 or ~> 2.4.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a8f3f720073b8b1ac4c978be25fa7960ed7fd44997420c304a4a2e200b596453"}, + "gettext": {:hex, :gettext, "0.20.0", "75ad71de05f2ef56991dbae224d35c68b098dd0e26918def5bb45591d5c8d429", [:mix], [], "hexpm", "1c03b177435e93a47441d7f681a7040bd2a816ece9e2666d1c9001035121eb3d"}, + "hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"}, + "icalendar": {:hex, :icalendar, "1.1.2", "5d0afff5d0143c5bd43f18ae32a777bf0fb9a724543ab05229a460d368f0a5e7", [:mix], [{:timex, "~> 3.4", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm", "2060f8e353fdf3047e95a3f012583dc3c0bbd7ca1010e32ed9e9fc5760ad4292"}, + "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, + "jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, + "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, + "parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"}, + "postgrex": {:hex, :postgrex, "0.16.5", "fcc4035cc90e23933c5d69a9cd686e329469446ef7abba2cf70f08e2c4b69810", [:mix], [{:connection, "~> 1.1", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "edead639dc6e882618c01d8fc891214c481ab9a3788dfe38dd5e37fd1d5fb2e8"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, + "telemetry": {:hex, :telemetry, "1.1.0", "a589817034a27eab11144ad24d5c0f9fab1f58173274b1e9bae7074af9cbee51", [:rebar3], [], "hexpm", "b727b2a1f75614774cff2d7565b64d0dfa5bd52ba517f16543e6fc7efcc0df48"}, + "timex": {:hex, :timex, "3.7.9", "790cdfc4acfce434e442f98c02ea6d84d0239073bfd668968f82ac63e9a6788d", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.1", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "64691582e5bb87130f721fc709acfb70f24405833998fabf35be968984860ce1"}, + "tzdata": {:hex, :tzdata, "1.1.1", "20c8043476dfda8504952d00adac41c6eda23912278add38edc140ae0c5bcc46", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a69cec8352eafcd2e198dea28a34113b60fdc6cb57eb5ad65c10292a6ba89787"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, +} diff --git a/holiday/priv/repo/migrations/20221003235923_create_holiday.exs b/holiday/priv/repo/migrations/20221003235923_create_holiday.exs new file mode 100644 index 0000000..be7bd9f --- /dev/null +++ b/holiday/priv/repo/migrations/20221003235923_create_holiday.exs @@ -0,0 +1,16 @@ +defmodule Holiday.Repo.Migrations.CreateHoliday do + use Ecto.Migration + + def change do + create table(:holiday) do + add(:title, :string, null: true) + add(:dStart, :date, null: true) + add(:dEnd, :date, null: true) + add(:uid, :binary_id, autogenerate: true) + add(:rules, :map, null: true) + add(:isConfirmed, :boolean, default: false) + end + + create(unique_index(:holiday, [:uid, :uid])) + end +end diff --git a/holiday/priv/repo/migrations/20221004010902_create_people.exs b/holiday/priv/repo/migrations/20221004010902_create_people.exs new file mode 100644 index 0000000..4336d64 --- /dev/null +++ b/holiday/priv/repo/migrations/20221004010902_create_people.exs @@ -0,0 +1,10 @@ +defmodule Holiday.Repo.Migrations.CreatePeople do + use Ecto.Migration + + def change do + create table(:people) do + add(:name, :string, null: false) + add(:age, :integer, default: 0) + end + end +end diff --git a/holiday/test/holiday_test.exs b/holiday/test/holiday_test.exs new file mode 100644 index 0000000..7c0403d --- /dev/null +++ b/holiday/test/holiday_test.exs @@ -0,0 +1,40 @@ +defmodule HolidayTest do + use ExUnit.Case + doctest Holiday + + test "init db" do + assert Holiday.init_db() != [] + end + + test "show_all_events" do + assert Holiday.show_all_events() == true + end + + test "2022-09-01 is holiday?" do + assert Holiday.is_holiday(~D[2022-09-01]) == true + end + + test "2022-03-24 is holiday?" do + assert Holiday.is_holiday(~D[2022-03-24]) == false + end + + test "time_until_holiday day?" do + assert Holiday.time_until_holiday(:day, ~U[2016-05-24 13:26:08Z]) == + 7.440185185185185 + end + + test "time_until_holiday hour?" do + assert Holiday.time_until_holiday(:hour, ~U[2016-05-24 13:26:08Z]) == + 178.56444444444443 + end + + test "time_until_holiday minute?" do + assert Holiday.time_until_holiday(:minute, ~U[2016-05-24 13:26:08Z]) == + 10713.866666666667 + end + + test "time_until_holiday second?" do + assert Holiday.time_until_holiday(:second, ~U[2016-05-24 13:26:08Z]) == + 642_832 + end +end diff --git a/holiday/test/test_helper.exs b/holiday/test/test_helper.exs new file mode 100644 index 0000000..869559e --- /dev/null +++ b/holiday/test/test_helper.exs @@ -0,0 +1 @@ +ExUnit.start()