diff --git a/config/config.exs b/config/config.exs index c48df79..4d33f6a 100644 --- a/config/config.exs +++ b/config/config.exs @@ -1,6 +1,6 @@ # This file is responsible for configuring your application # and its dependencies with the aid of the Mix.Config module. -use Mix.Config +import Config # This configuration is loaded before any dependency and is restricted # to this project. If another project depends on this project, this diff --git a/lib/ex_ical.ex b/lib/ex_ical.ex index 6785351..24cc679 100644 --- a/lib/ex_ical.ex +++ b/lib/ex_ical.ex @@ -23,8 +23,8 @@ defmodule ExIcal do alias ExIcal.{Parser,Recurrence,Utils,Event} - @spec parse(String.t) :: [%Event{}] - defdelegate parse(data), to: Parser + @spec parse(String.t, String.t|nil) :: [%Event{}] + defdelegate parse(data, locale \\ nil), to: Parser @spec add_recurring_events([%Event{}]) :: [%Event{}] defdelegate add_recurring_events(events), to: Recurrence diff --git a/lib/ex_ical/date_parser.ex b/lib/ex_ical/date_parser.ex index 6f6a058..dd8b434 100644 --- a/lib/ex_ical/date_parser.ex +++ b/lib/ex_ical/date_parser.ex @@ -67,54 +67,44 @@ defmodule ExIcal.DateParser do @type valid_timezone :: String.t | :utc | :local - @spec parse(String.t, valid_timezone | nil) :: %DateTime{} - def parse(data, tzid \\ nil) + @spec parse(String.t, valid_timezone | nil, String.t | nil) :: %DateTime{} + def parse(data, tzid \\ nil, locale \\ nil) # Date Format: "19690620T201804Z", Timezone: * def parse(<< year :: binary-size(4), month :: binary-size(2), day :: binary-size(2), "T", hour :: binary-size(2), minutes :: binary-size(2), seconds :: binary-size(2), "Z" >>, - _timezone) do - date = {year, month, day} - time = {hour, minutes, seconds} - - {to_integers(date), to_integers(time)} - |> NaiveDateTime.from_erl!() - |> DateTime.from_naive!("Etc/UTC") - end - - # Date Format: "19690620T201804", Timezone: nil - def parse(<< year :: binary-size(4), month :: binary-size(2), day :: binary-size(2), "T", - hour :: binary-size(2), minutes :: binary-size(2), seconds :: binary-size(2) >>, - nil) do + _timezone, locale) do date = {year, month, day} time = {hour, minutes, seconds} {to_integers(date), to_integers(time)} |> NaiveDateTime.from_erl!() + #|> Timex.to_datetime(locale || timezone || "Etc/UTC") |> DateTime.from_naive!("Etc/UTC") + |> maybe_shift_zone(locale) end # Date Format: "19690620T201804", Timezone: * def parse(<< year :: binary-size(4), month :: binary-size(2), day :: binary-size(2), "T", hour :: binary-size(2), minutes :: binary-size(2), seconds :: binary-size(2) >>, - timezone) do + timezone, locale) do date = {year, month, day} time = {hour, minutes, seconds} {to_integers(date), to_integers(time)} - |> Timex.to_datetime(timezone) + |> Timex.to_datetime(locale || timezone || "Etc/UTC") end # Date Format: "19690620Z", Timezone: * - def parse(<< year :: binary-size(4), month :: binary-size(2), day :: binary-size(2), "Z" >>, _timezone) do + def parse(<< year :: binary-size(4), month :: binary-size(2), day :: binary-size(2), "Z" >>, _timezone, locale) do {to_integers({year, month, day}), {0, 0, 0}} - |> Timex.to_datetime() + |> Timex.to_datetime(locale || "Etc/UTC") end # Date Format: "19690620", Timezone: * - def parse(<< year :: binary-size(4), month :: binary-size(2), day :: binary-size(2) >>, _timezone) do + def parse(<< year :: binary-size(4), month :: binary-size(2), day :: binary-size(2) >>, timezone, locale) do {to_integers({year, month, day}), {0, 0, 0}} - |> Timex.to_datetime() + |> Timex.to_datetime(locale || timezone || "Etc/UTC") end @spec to_integers({String.t, String.t, String.t}) :: {integer, integer, integer} @@ -125,4 +115,7 @@ defmodule ExIcal.DateParser do String.to_integer(str3) } end + + defp maybe_shift_zone(datetime, nil), do: datetime + defp maybe_shift_zone(datetime, timezone), do: DateTime.shift_zone!(datetime, timezone) end diff --git a/lib/ex_ical/parser.ex b/lib/ex_ical/parser.ex index 7339dbe..4367e64 100644 --- a/lib/ex_ical/parser.ex +++ b/lib/ex_ical/parser.ex @@ -31,8 +31,8 @@ defmodule ExIcal.Parser do ``` """ - @spec parse(String.t) :: [%Event{}] - def parse(data) do + @spec parse(String.t, String.t|nil) :: [%Event{}] + def parse(data, locale \\ nil) do data |> String.replace(~s"\n\t", ~S"\n") |> String.replace(~s"\n\x20", ~S"\n") @@ -41,22 +41,22 @@ defmodule ExIcal.Parser do |> Enum.reduce(%{events: []}, fn(line, data) -> line |> String.trim() - |> parse_line(data) + |> parse_line(data, locale) end) |> Map.get(:events) end - defp parse_line("BEGIN:VEVENT" <> _, data), do: %{data | events: [%Event{} | data[:events]]} - defp parse_line("DTSTART" <> start, data), do: data |> put_to_map(:start, process_date(start, data[:tzid])) - defp parse_line("DTEND" <> endd, data), do: data |> put_to_map(:end, process_date(endd, data[:tzid])) - defp parse_line("DTSTAMP" <> stamp, data), do: data |> put_to_map(:stamp, process_date(stamp, data[:tzid])) - defp parse_line("SUMMARY:" <> summary, data), do: data |> put_to_map(:summary, process_string(summary)) - defp parse_line("DESCRIPTION:" <> description, data), do: data |> put_to_map(:description, process_string(description)) - defp parse_line("UID:" <> uid, data), do: data |> put_to_map(:uid, uid) - defp parse_line("RRULE:" <> rrule, data), do: data |> put_to_map(:rrule, process_rrule(rrule, data[:tzid])) - defp parse_line("TZID:" <> tzid, data), do: data |> Map.put(:tzid, tzid) - defp parse_line("CATEGORIES:" <> categories, data), do: data |> put_to_map(:categories, String.split(categories, ",")) - defp parse_line(_, data), do: data + defp parse_line("BEGIN:VEVENT" <> _, data, _locale), do: %{data | events: [%Event{} | data[:events]]} + defp parse_line("DTSTART" <> start, data, locale), do: data |> put_to_map(:start, process_date(start, data[:tzid], locale)) + defp parse_line("DTEND" <> endd, data, locale), do: data |> put_to_map(:end, process_date(endd, data[:tzid], locale)) + defp parse_line("DTSTAMP" <> stamp, data, locale), do: data |> put_to_map(:stamp, process_date(stamp, data[:tzid], locale)) + defp parse_line("SUMMARY:" <> summary, data, _locale), do: data |> put_to_map(:summary, process_string(summary)) + defp parse_line("DESCRIPTION:" <> description, data, _locale), do: data |> put_to_map(:description, process_string(description)) + defp parse_line("UID:" <> uid, data, _locale), do: data |> put_to_map(:uid, uid) + defp parse_line("RRULE:" <> rrule, data, _locale), do: data |> put_to_map(:rrule, process_rrule(rrule, data[:tzid])) + defp parse_line("TZID:" <> tzid, data, _locale), do: data |> Map.put(:tzid, tzid) + defp parse_line("CATEGORIES:" <> categories, data, _locale), do: data |> put_to_map(:categories, String.split(categories, ",")) + defp parse_line(_, data, _locale), do: data defp put_to_map(%{events: [event | events]} = data, key, value) do updated_event = %{event | key => value} @@ -64,14 +64,14 @@ defmodule ExIcal.Parser do end defp put_to_map(data, _key, _value), do: data - defp process_date(":" <> date, tzid), do: DateParser.parse(date, tzid) - defp process_date(";" <> date, _) do + defp process_date(":" <> date, tzid, locale), do: DateParser.parse(date, tzid, locale) + defp process_date(";" <> date, _, locale) do [timezone, date] = date |> String.split(":") timezone = case timezone do "TZID=" <> timezone -> timezone _ -> nil end - DateParser.parse(date, timezone) + DateParser.parse(date, timezone, locale) end defp process_rrule(rrule, tzid) do diff --git a/mix.exs b/mix.exs index 8d76e19..56df15e 100644 --- a/mix.exs +++ b/mix.exs @@ -3,7 +3,7 @@ defmodule ExIcal.Mixfile do def project do [app: :ex_ical, - version: "0.2.0", + version: "0.3.0", elixir: "~> 1.4", description: "ICalendar parser.", package: package(), @@ -33,7 +33,7 @@ defmodule ExIcal.Mixfile do defp deps() do [ {:ex_doc, "~> 0.16", only: :dev, runtime: false}, - {:credo, "~> 0.9.1", only: [:dev, :test], runtime: false}, + {:credo, "~> 1.7", only: [:dev, :test], runtime: false}, {:timex, "~> 3.1"} ] end diff --git a/mix.lock b/mix.lock index f0a9ec9..e976e7f 100644 --- a/mix.lock +++ b/mix.lock @@ -1,20 +1,28 @@ %{ - "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, - "certifi": {:hex, :certifi, "2.3.1", "d0f424232390bf47d82da8478022301c561cf6445b5b5fb6a84d49a9e76d2639", [:rebar3], [{:parse_trans, "3.2.0", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, - "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm"}, - "credo": {:hex, :credo, "0.9.2", "841d316612f568beb22ba310d816353dddf31c2d94aa488ae5a27bb53760d0bf", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:poison, ">= 0.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, - "earmark": {:hex, :earmark, "1.2.2", "f718159d6b65068e8daeef709ccddae5f7fdc770707d82e7d126f584cd925b74", [:mix], [], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.16.1", "b4b8a23602b4ce0e9a5a960a81260d1f7b29635b9652c67e95b0c2f7ccee5e81", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, - "gettext": {:hex, :gettext, "0.15.0", "40a2b8ce33a80ced7727e36768499fc9286881c43ebafccae6bab731e2b2b8ce", [:mix], [], "hexpm"}, - "hackney": {:hex, :hackney, "1.12.1", "8bf2d0e11e722e533903fe126e14d6e7e94d9b7983ced595b75f532e04b7fdc7", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, - "idna": {:hex, :idna, "5.1.1", "cbc3b2fa1645113267cc59c760bafa64b2ea0334635ef06dbac8801e42f7279c", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, - "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, - "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, - "parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], [], "hexpm"}, - "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, + "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, + "certifi": {:hex, :certifi, "2.14.0", "ed3bef654e69cde5e6c022df8070a579a79e8ba2368a00acf3d75b82d9aceeed", [:rebar3], [], "hexpm", "ea59d87ef89da429b8e905264fdec3419f84f2215bb3d81e07a18aac919026c3"}, + "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"}, + "credo": {:hex, :credo, "1.7.11", "d3e805f7ddf6c9c854fd36f089649d7cf6ba74c42bc3795d587814e3c9847102", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "56826b4306843253a66e47ae45e98e7d284ee1f95d53d1612bb483f88a8cf219"}, + "earmark": {:hex, :earmark, "1.2.2", "f718159d6b65068e8daeef709ccddae5f7fdc770707d82e7d126f584cd925b74", [:mix], [], "hexpm", "59514c4a207f9f25c5252e09974367718554b6a0f41fe39f7dc232168f9cb309"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.43", "34b2f401fe473080e39ff2b90feb8ddfeef7639f8ee0bbf71bb41911831d77c5", [:mix], [], "hexpm", "970a3cd19503f5e8e527a190662be2cee5d98eed1ff72ed9b3d1a3d466692de8"}, + "ex_doc": {:hex, :ex_doc, "0.37.3", "f7816881a443cd77872b7d6118e8a55f547f49903aef8747dbcb345a75b462f9", [:mix], [{:earmark_parser, "~> 1.4.42", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "e6aebca7156e7c29b5da4daa17f6361205b2ae5f26e5c7d8ca0d3f7e18972233"}, + "expo": {:hex, :expo, "1.1.0", "f7b9ed7fb5745ebe1eeedf3d6f29226c5dd52897ac67c0f8af62a07e661e5c75", [:mix], [], "hexpm", "fbadf93f4700fb44c331362177bdca9eeb8097e8b0ef525c9cc501cb9917c960"}, + "file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"}, + "gettext": {:hex, :gettext, "0.26.2", "5978aa7b21fada6deabf1f6341ddba50bc69c999e812211903b169799208f2a8", [:mix], [{:expo, "~> 0.5.1 or ~> 1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "aa978504bcf76511efdc22d580ba08e2279caab1066b76bb9aa81c4a1e0a32a5"}, + "hackney": {:hex, :hackney, "1.23.0", "55cc09077112bcb4a69e54be46ed9bc55537763a96cd4a80a221663a7eafd767", [:rebar3], [{:certifi, "~> 2.14.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.4.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", "6cd1c04cd15c81e5a493f167b226a15f0938a84fc8f0736ebe4ddcab65c0b44e"}, + "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.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, + "makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"}, + "makeup_elixir": {:hex, :makeup_elixir, "1.0.1", "e928a4f984e795e41e3abd27bfc09f51db16ab8ba1aebdba2b3a575437efafc2", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "7284900d412a3e5cfd97fdaed4f5ed389b8f2b4cb49efc0eb3bd10e2febf9507"}, + "makeup_erlang": {:hex, :makeup_erlang, "1.0.2", "03e1804074b3aa64d5fad7aa64601ed0fb395337b982d9bcf04029d68d51b6a7", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "af33ff7ef368d5893e4a267933e7744e46ce3cf1f61e2dccf53a111ed3aa3727"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, + "mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, + "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"}, + "poison": {:hex, :poison, "6.0.0", "9bbe86722355e36ffb62c51a552719534257ba53f3271dacd20fbbd6621a583a", [:mix], [{:decimal, "~> 2.1", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "bb9064632b94775a3964642d6a78281c07b7be1319e0016e1643790704e739a2"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "ssl_verify_hostname": {:hex, :ssl_verify_hostname, "1.0.6", "45866d958d9ae51cfe8fef0050ab8054d25cba23ace43b88046092aa2c714645", [:make], []}, - "timex": {:hex, :timex, "3.3.0", "e0695aa0ddb37d460d93a2db34d332c2c95a40c27edf22fbfea22eb8910a9c8d", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"}, - "tzdata": {:hex, :tzdata, "0.5.16", "13424d3afc76c68ff607f2df966c0ab4f3258859bbe3c979c9ed1606135e7352", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, - "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"}, + "timex": {:hex, :timex, "3.7.11", "bb95cb4eb1d06e27346325de506bcc6c30f9c6dea40d1ebe390b262fad1862d1", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.20", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.1", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "8b9024f7efbabaf9bd7aa04f65cf8dcd7c9818ca5737677c7b76acbc6a94d1aa"}, + "tzdata": {:hex, :tzdata, "1.1.3", "b1cef7bb6de1de90d4ddc25d33892b32830f907e7fc2fccd1e7e22778ab7dfbc", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "d4ca85575a064d29d4e94253ee95912edfb165938743dbf002acdf0dcecb0c28"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, } diff --git a/test/ex_ical/date_parser_test.exs b/test/ex_ical/date_parser_test.exs index 5a39e7c..7e68568 100644 --- a/test/ex_ical/date_parser_test.exs +++ b/test/ex_ical/date_parser_test.exs @@ -5,10 +5,13 @@ defmodule ExIcal.DateParserTest do doctest DateParser - date_match = %{year: 1969, month: 6, day: 20} - datetime_match = %{year: 1969, month: 6, day: 20, - hour: 20, minute: 18, second: 4} + date_match = %{year: 1969, month: 6, day: 20} + datetime_match = %{year: 1969, month: 6, day: 20, + hour: 20, minute: 18, second: 4} + chicago_match = %{year: 1969, month: 6, day: 20, + hour: 15, minute: 18, second: 4} chicago_tzmatch = "America/Chicago" + berlin_tzmatch = "Europe/Berlin" utc_tzmatch = "UTC" allowed_date_formats = [ @@ -16,7 +19,7 @@ defmodule ExIcal.DateParserTest do # Input Datestring | Parsed Date | Timezone When Global TZID = ? | # | | nil | America/Chicago | #------------------+--------------------------------------------------+ - { "19690620", date_match, utc_tzmatch, utc_tzmatch,}, + { "19690620", date_match, utc_tzmatch, chicago_tzmatch,}, { "19690620Z", date_match, utc_tzmatch, utc_tzmatch,}, { "19690620T201804", datetime_match, utc_tzmatch, chicago_tzmatch,}, {"19690620T201804Z", datetime_match, utc_tzmatch, utc_tzmatch,}, @@ -53,4 +56,29 @@ defmodule ExIcal.DateParserTest do assert_subset expected.timezone, parsed_date.time_zone end end + + allowed_date_formats = [ + #------------------+----------------------------------------------------------------+ + # Input Datestring | Parsed Date | Timezone When Global TZID = ? | Locale TZ | + # | | nil | America/Chicago | | + #------------------+----------------------------------------------------------------+ + { "19690620", date_match, utc_tzmatch, berlin_tzmatch, chicago_tzmatch}, + { "19690620Z", date_match, utc_tzmatch, utc_tzmatch, chicago_tzmatch}, + { "19690620T201804", datetime_match, utc_tzmatch, berlin_tzmatch, chicago_tzmatch}, + {"19690620T201804Z", chicago_match, utc_tzmatch, utc_tzmatch, chicago_tzmatch}, + ] + + for {input, date_match, _no_tzid, global_tzid, locale_tzid} <- allowed_date_formats do + @tag input: input + @tag tzid: global_tzid + @tag locale_tzid: locale_tzid + @tag expected: %{date: date_match, timezone: chicago_tzmatch} + test ~s[DateParser.parse/2 locale #{locale_tzid} trumps everything else for input #{input}], + %{input: input, expected: expected, tzid: tzid} do + parsed_date = DateParser.parse(input, tzid, expected.timezone) + + assert_subset expected.date, parsed_date + assert_subset expected.timezone, parsed_date.time_zone + end + end end diff --git a/test/ex_ical_date_formats_test.exs b/test/ex_ical_date_formats_test.exs index 3431d8c..2fb8eac 100644 --- a/test/ex_ical_date_formats_test.exs +++ b/test/ex_ical_date_formats_test.exs @@ -26,7 +26,7 @@ defmodule ExIcal.DateFormatsTest do # DTSTART input | Parsed Date | Timezone with Global TZID = ? | # | | nil | America/Chicago | #---------------------------------------------+---------------+----------------+-----------------+ - { "DTSTART:19690620", date_match, utc_tzmatch, utc_tzmatch,}, + { "DTSTART:19690620", date_match, utc_tzmatch, chicago_tzmatch,}, { "DTSTART:19690620Z", date_match, utc_tzmatch, utc_tzmatch,}, { "DTSTART:19690620T201804", datetime_match, utc_tzmatch, chicago_tzmatch,}, { "DTSTART:19690620T201804Z", datetime_match, utc_tzmatch, utc_tzmatch,},