From fc9f6df0234305769732738c6d4d0abc985dcb57 Mon Sep 17 00:00:00 2001 From: Douglas Vought Date: Fri, 12 Jul 2024 05:21:33 -0400 Subject: [PATCH 1/6] Implement big year parsing --- lib/elixir/lib/calendar/iso.ex | 102 ++++++++++++++++++ lib/elixir/test/elixir/calendar/date_test.exs | 4 + .../test/elixir/calendar/datetime_test.exs | 48 +++++++++ lib/elixir/test/elixir/calendar/iso_test.exs | 33 ++++++ 4 files changed, 187 insertions(+) diff --git a/lib/elixir/lib/calendar/iso.ex b/lib/elixir/lib/calendar/iso.ex index dca389bc2a4..468cfe85f1e 100644 --- a/lib/elixir/lib/calendar/iso.ex +++ b/lib/elixir/lib/calendar/iso.ex @@ -216,6 +216,27 @@ defmodule Calendar.ISO do ] end + [match_big_year, guard_big_year, match_rest_of_date, guard_rest_of_date, read_rest_of_date] = + quote do + [ + <>, + y1 >= ?0 and y1 <= ?9 and + (y2 >= ?0 and y2 <= ?9) and + (y3 >= ?0 and y3 <= ?9) and + (y4 >= ?0 and y4 <= ?9) and + (y5 >= ?0 and y5 <= ?9), + <>, + m1 >= ?0 and m1 <= ?9 and + (m2 >= ?0 and m1 <= ?9) and + (d1 >= ?0 and d1 <= ?9) and + (d2 >= ?0 and d2 <= ?9), + { + (m1 - ?0) * 10 + (m2 - ?0), + (d1 - ?0) * 10 + (d2 - ?0) + } + ] + end + [match_basic_time, match_ext_time, guard_time, read_time] = quote do [ @@ -421,6 +442,18 @@ defmodule Calendar.ISO do parse_formatted_date(year, month, day, multiplier) end + defp do_parse_date(unquote(match_big_year) <> rest, multiplier, :extended) + when unquote(guard_big_year) do + <> = unquote(match_big_year) + {year, rest} = reduce_big_year(rest, [y5, y4, y3, y2, y1]) + + case big_year_rest(rest) do + :error -> {:error, :invalid_format} + {{month, day}, ""} -> parse_formatted_date(year, month, day, multiplier) + {{_month, _day}, _rest} -> {:error, :invalid_format} + end + end + defp do_parse_date(_, _, _) do {:error, :invalid_format} end @@ -435,6 +468,37 @@ defmodule Calendar.ISO do end end + defp reduce_big_year(<>, digits) when y >= ?0 and y <= ?9 do + reduce_big_year(rest, [y | digits]) + end + + defp reduce_big_year("", _digits) do + {:error, :invalid_format} + end + + defp reduce_big_year(rest, digits) do + {year, _} = + List.foldl(digits, {0, 1}, fn digit, {year, n} -> + {(digit - ?0) * n + year, 10 * n} + end) + + {year, rest} + end + + defp big_year_rest(unquote(match_rest_of_date)) when unquote(guard_rest_of_date) do + {month, day} = unquote(read_rest_of_date) + {{month, day}, ""} + end + + defp big_year_rest(unquote(match_rest_of_date) <> rest) when unquote(guard_rest_of_date) do + {month, day} = unquote(read_rest_of_date) + {{month, day}, rest} + end + + defp big_year_rest(_rest) do + :error + end + @doc """ Parses a naive datetime `string` in the `:extended` format. @@ -518,6 +582,25 @@ defmodule Calendar.ISO do parse_formatted_naive_datetime(year, month, day, hour, minute, second, rest, multiplier) end + defp do_parse_naive_datetime(unquote(match_big_year) <> rest, multiplier, :extended) + when unquote(guard_big_year) do + <> = unquote(match_big_year) + {year, rest} = reduce_big_year(rest, [y5, y4, y3, y2, y1]) + + case big_year_rest(rest) do + :error -> + {:error, :invalid_format} + + {{month, day}, <>} + when datetime_sep in @datetime_seps and unquote(guard_time) -> + {hour, minute, second} = unquote(read_time) + parse_formatted_naive_datetime(year, month, day, hour, minute, second, rest, multiplier) + + {{_month, _day}, _} -> + {:error, :invalid_format} + end + end + defp do_parse_naive_datetime(_, _, _) do {:error, :invalid_format} end @@ -622,6 +705,25 @@ defmodule Calendar.ISO do parse_formatted_utc_datetime(year, month, day, hour, minute, second, rest, multiplier) end + defp do_parse_utc_datetime(unquote(match_big_year) <> rest, multiplier, :extended) + when unquote(guard_big_year) do + <> = unquote(match_big_year) + {year, rest} = reduce_big_year(rest, [y5, y4, y3, y2, y1]) + + case big_year_rest(rest) do + :error -> + {:error, :invalid_format} + + {{_month, _day}, ""} -> + {:error, :invalid_format} + + {{month, day}, <>} + when datetime_sep in @datetime_seps and unquote(guard_time) -> + {hour, minute, second} = unquote(read_time) + parse_formatted_utc_datetime(year, month, day, hour, minute, second, rest, multiplier) + end + end + defp do_parse_utc_datetime(_, _, _) do {:error, :invalid_format} end diff --git a/lib/elixir/test/elixir/calendar/date_test.exs b/lib/elixir/test/elixir/calendar/date_test.exs index 09c5969c855..57749c7a73f 100644 --- a/lib/elixir/test/elixir/calendar/date_test.exs +++ b/lib/elixir/test/elixir/calendar/date_test.exs @@ -10,6 +10,10 @@ defmodule DateTest do assert ~D[2000-01-01] == %Date{calendar: Calendar.ISO, year: 2000, month: 1, day: 1} + assert ~D[99999-01-01] == %Date{calendar: Calendar.ISO, year: 99_999, month: 1, day: 1} + assert ~D[+99999-01-01] == %Date{calendar: Calendar.ISO, year: 99_999, month: 1, day: 1} + assert ~D[-99999-01-01] == %Date{calendar: Calendar.ISO, year: -99_999, month: 1, day: 1} + assert ~D[20001-01-01 Calendar.Holocene] == %Date{calendar: Calendar.Holocene, year: 20001, month: 1, day: 1} diff --git a/lib/elixir/test/elixir/calendar/datetime_test.exs b/lib/elixir/test/elixir/calendar/datetime_test.exs index ecd8060e353..3fc58ebc775 100644 --- a/lib/elixir/test/elixir/calendar/datetime_test.exs +++ b/lib/elixir/test/elixir/calendar/datetime_test.exs @@ -52,6 +52,54 @@ defmodule DateTimeTest do zone_abbr: "UTC" } + assert ~U[10000-07-08 18:35:22.193042Z] == + %DateTime{ + calendar: Calendar.ISO, + year: 10_000, + month: 7, + day: 8, + hour: 18, + minute: 35, + second: 22, + microsecond: {193_042, 6}, + std_offset: 0, + utc_offset: 0, + time_zone: "Etc/UTC", + zone_abbr: "UTC" + } + + assert ~U[-10000-07-08 18:35:22.193042Z] == + %DateTime{ + calendar: Calendar.ISO, + year: -10_000, + month: 7, + day: 8, + hour: 18, + minute: 35, + second: 22, + microsecond: {193_042, 6}, + std_offset: 0, + utc_offset: 0, + time_zone: "Etc/UTC", + zone_abbr: "UTC" + } + + assert ~U[-12345-07-08T18:35:22.2288Z] == + %DateTime{ + calendar: Calendar.ISO, + year: -12_345, + month: 7, + day: 8, + hour: 18, + minute: 35, + second: 22, + microsecond: {228_800, 4}, + std_offset: 0, + utc_offset: 0, + time_zone: "Etc/UTC", + zone_abbr: "UTC" + } + assert ~U[2000-01-01 12:34:56Z Calendar.Holocene] == %DateTime{ calendar: Calendar.Holocene, diff --git a/lib/elixir/test/elixir/calendar/iso_test.exs b/lib/elixir/test/elixir/calendar/iso_test.exs index a3ce35c25b2..6a821f50913 100644 --- a/lib/elixir/test/elixir/calendar/iso_test.exs +++ b/lib/elixir/test/elixir/calendar/iso_test.exs @@ -15,6 +15,7 @@ defmodule Calendar.ISOTest do assert {9999, 1, 1} == iso_day_roundtrip(9999, 1, 1) assert {9996, 12, 31} == iso_day_roundtrip(9996, 12, 31) assert {9996, 1, 1} == iso_day_roundtrip(9996, 1, 1) + assert {55_555, 5, 5} == iso_day_roundtrip(55_555, 5, 5) end test "with negative dates" do @@ -32,6 +33,8 @@ defmodule Calendar.ISOTest do assert {-9996, 12, 31} == iso_day_roundtrip(-9996, 12, 31) assert {-9996, 1, 1} == iso_day_roundtrip(-9996, 1, 1) + + assert {-55_555, 5, 5} == iso_day_roundtrip(-55_555, 5, 5) end end @@ -126,6 +129,16 @@ defmodule Calendar.ISOTest do assert Calendar.ISO.parse_date("20150123") == {:error, :invalid_format} assert Calendar.ISO.parse_date("2015-01-23") == {:ok, {2015, 1, 23}} end + + test "parses big years" do + assert Calendar.ISO.parse_date("+201500-01-23") == {:ok, {201_500, 1, 23}} + assert Calendar.ISO.parse_date("201500-01-23") == {:ok, {201_500, 1, 23}} + assert Calendar.ISO.parse_date("-201500-01-23") == {:ok, {-201_500, 1, 23}} + end + + test "fails with bad data" do + assert Calendar.ISO.parse_date("+201500-01-23 ") == {:error, :invalid_format} + end end describe "parse_date/2" do @@ -238,6 +251,9 @@ defmodule Calendar.ISOTest do assert Calendar.ISO.parse_naive_datetime("2015:01:23 23-50-07") == {:error, :invalid_format} assert Calendar.ISO.parse_naive_datetime("2015-01-23P23:50:07") == {:error, :invalid_format} + assert Calendar.ISO.parse_naive_datetime("303030-01-12X23:11:40") == + {:error, :invalid_format} + assert Calendar.ISO.parse_naive_datetime("2015-01-23 23:50:07A") == {:error, :invalid_format} end @@ -290,6 +306,17 @@ defmodule Calendar.ISOTest do assert Calendar.ISO.parse_naive_datetime("2015-01-23 235007.123") == {:error, :invalid_format} end + + test "supports big years" do + assert Calendar.ISO.parse_naive_datetime("123456-12-01 13:27:34") == + {:ok, {123_456, 12, 1, 13, 27, 34, {0, 0}}} + + assert Calendar.ISO.parse_naive_datetime("+123456-12-01 13:27:34") == + {:ok, {123_456, 12, 1, 13, 27, 34, {0, 0}}} + + assert Calendar.ISO.parse_naive_datetime("-123456-12-01 13:27:34") == + {:ok, {-123_456, 12, 1, 13, 27, 34, {0, 0}}} + end end describe "parse_naive_datetime/2" do @@ -299,6 +326,9 @@ defmodule Calendar.ISOTest do assert Calendar.ISO.parse_naive_datetime("2015-01-23 23:50:07.123", :basic) == {:error, :invalid_format} + + assert Calendar.ISO.parse_naive_datetime("55555-01-23 23:50:07.123", :basic) == + {:error, :invalid_format} end test "allows enforcing extended formats" do @@ -344,6 +374,9 @@ defmodule Calendar.ISOTest do assert Calendar.ISO.parse_utc_datetime("2015-01-23T23:50:07.123-02:30") == {:ok, {2015, 1, 24, 2, 20, 7, {123_000, 3}}, -9000} + assert Calendar.ISO.parse_utc_datetime("200015-01-23T23:50:07.123-02:30") == + {:ok, {200_015, 1, 24, 2, 20, 7, {123_000, 3}}, -9000} + assert Calendar.ISO.parse_utc_datetime("2015-01-23T23:50:07.123-00:00") == {:error, :invalid_format} From a9f2fef7975ef2c5a9d1481a7f78a67c001eb301 Mon Sep 17 00:00:00 2001 From: Douglas Vought Date: Sat, 13 Jul 2024 04:53:13 -0400 Subject: [PATCH 2/6] Fix up naming, use `Enum.reduce/3` instead of `List.foldl/3`, format --- lib/elixir/lib/calendar/iso.ex | 48 ++++++++++++++++------------------ 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/lib/elixir/lib/calendar/iso.ex b/lib/elixir/lib/calendar/iso.ex index 468cfe85f1e..59f8c07efec 100644 --- a/lib/elixir/lib/calendar/iso.ex +++ b/lib/elixir/lib/calendar/iso.ex @@ -216,19 +216,14 @@ defmodule Calendar.ISO do ] end - [match_big_year, guard_big_year, match_rest_of_date, guard_rest_of_date, read_rest_of_date] = + [match_big_year, guard_big_year, match_big_year_rest, guard_big_year_rest, read_big_year_rest] = quote do [ <>, - y1 >= ?0 and y1 <= ?9 and - (y2 >= ?0 and y2 <= ?9) and - (y3 >= ?0 and y3 <= ?9) and - (y4 >= ?0 and y4 <= ?9) and - (y5 >= ?0 and y5 <= ?9), - <>, - m1 >= ?0 and m1 <= ?9 and - (m2 >= ?0 and m1 <= ?9) and - (d1 >= ?0 and d1 <= ?9) and + y1 >= ?0 and y1 <= ?9 and (y2 >= ?0 and y2 <= ?9) and + (y3 >= ?0 and y3 <= ?9) and (y4 >= ?0 and y4 <= ?9) and (y5 >= ?0 and y5 <= ?9), + <<@ext_date_sep, m1, m2, @ext_date_sep, d1, d2>>, + m1 >= ?0 and m1 <= ?9 and (m2 >= ?0 and m1 <= ?9) and (d1 >= ?0 and d1 <= ?9) and (d2 >= ?0 and d2 <= ?9), { (m1 - ?0) * 10 + (m2 - ?0), @@ -445,9 +440,9 @@ defmodule Calendar.ISO do defp do_parse_date(unquote(match_big_year) <> rest, multiplier, :extended) when unquote(guard_big_year) do <> = unquote(match_big_year) - {year, rest} = reduce_big_year(rest, [y5, y4, y3, y2, y1]) + {year, rest} = parse_big_year(rest, [y5, y4, y3, y2, y1]) - case big_year_rest(rest) do + case parse_big_year_rest(rest) do :error -> {:error, :invalid_format} {{month, day}, ""} -> parse_formatted_date(year, month, day, multiplier) {{_month, _day}, _rest} -> {:error, :invalid_format} @@ -468,34 +463,35 @@ defmodule Calendar.ISO do end end - defp reduce_big_year(<>, digits) when y >= ?0 and y <= ?9 do - reduce_big_year(rest, [y | digits]) + defp parse_big_year(<>, digits) when y >= ?0 and y <= ?9 do + parse_big_year(rest, [y | digits]) end - defp reduce_big_year("", _digits) do + defp parse_big_year("", _digits) do {:error, :invalid_format} end - defp reduce_big_year(rest, digits) do + defp parse_big_year(rest, digits) do {year, _} = - List.foldl(digits, {0, 1}, fn digit, {year, n} -> + Enum.reduce(digits, {0, 1}, fn digit, {year, n} -> {(digit - ?0) * n + year, 10 * n} end) {year, rest} end - defp big_year_rest(unquote(match_rest_of_date)) when unquote(guard_rest_of_date) do - {month, day} = unquote(read_rest_of_date) + defp parse_big_year_rest(unquote(match_big_year_rest)) when unquote(guard_big_year_rest) do + {month, day} = unquote(read_big_year_rest) {{month, day}, ""} end - defp big_year_rest(unquote(match_rest_of_date) <> rest) when unquote(guard_rest_of_date) do - {month, day} = unquote(read_rest_of_date) + defp parse_big_year_rest(unquote(match_big_year_rest) <> rest) + when unquote(guard_big_year_rest) do + {month, day} = unquote(read_big_year_rest) {{month, day}, rest} end - defp big_year_rest(_rest) do + defp parse_big_year_rest(_rest) do :error end @@ -585,9 +581,9 @@ defmodule Calendar.ISO do defp do_parse_naive_datetime(unquote(match_big_year) <> rest, multiplier, :extended) when unquote(guard_big_year) do <> = unquote(match_big_year) - {year, rest} = reduce_big_year(rest, [y5, y4, y3, y2, y1]) + {year, rest} = parse_big_year(rest, [y5, y4, y3, y2, y1]) - case big_year_rest(rest) do + case parse_big_year_rest(rest) do :error -> {:error, :invalid_format} @@ -708,9 +704,9 @@ defmodule Calendar.ISO do defp do_parse_utc_datetime(unquote(match_big_year) <> rest, multiplier, :extended) when unquote(guard_big_year) do <> = unquote(match_big_year) - {year, rest} = reduce_big_year(rest, [y5, y4, y3, y2, y1]) + {year, rest} = parse_big_year(rest, [y5, y4, y3, y2, y1]) - case big_year_rest(rest) do + case parse_big_year_rest(rest) do :error -> {:error, :invalid_format} From f27be1fc05ab2378a6dd11baec0712f9bda2b153 Mon Sep 17 00:00:00 2001 From: Douglas Vought Date: Sat, 13 Jul 2024 04:59:59 -0400 Subject: [PATCH 3/6] Add tests --- lib/elixir/test/elixir/calendar/date_test.exs | 19 +++++++++++++++++-- lib/elixir/test/elixir/calendar/iso_test.exs | 16 ++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/lib/elixir/test/elixir/calendar/date_test.exs b/lib/elixir/test/elixir/calendar/date_test.exs index 57749c7a73f..fba39da5c72 100644 --- a/lib/elixir/test/elixir/calendar/date_test.exs +++ b/lib/elixir/test/elixir/calendar/date_test.exs @@ -33,6 +33,10 @@ defmodule DateTest do ~s/cannot parse "20001-50-50" as Date for Calendar.Holocene, reason: :invalid_date/, fn -> Code.eval_string("~D[20001-50-50 Calendar.Holocene]") end + assert_raise ArgumentError, + ~s/cannot parse "555555-55-55" as Date for Calendar.ISO, reason: :invalid_date/, + fn -> Code.eval_string("~D[555555-55-55]") end + assert_raise UndefinedFunctionError, fn -> Code.eval_string("~D[2000-01-01 UnknownCalendar]") end @@ -54,6 +58,14 @@ defmodule DateTest do assert to_string(%{date2 | calendar: FakeCalendar}) == "31/12/5874897" assert Date.to_string(%{date2 | calendar: FakeCalendar}) == "31/12/5874897" + + date3 = Date.new!(-5_874_897, 12, 31) + assert to_string(date3) == "-5874897-12-31" + assert Date.to_string(date3) == "-5874897-12-31" + assert Date.to_string(Map.from_struct(date3)) + + assert to_string(%{date3 | calendar: FakeCalendar}) == "31/12/-5874897" + assert Date.to_string(%{date3 | calendar: FakeCalendar}) == "31/12/-5874897" end test "inspect/1" do @@ -63,8 +75,11 @@ defmodule DateTest do date = %{~D[2000-01-01] | calendar: FakeCalendar} assert inspect(date) == "~D[1/1/2000 FakeCalendar]" - assert inspect(Date.new!(5_874_897, 12, 31)) == "Date.new!(5874897, 12, 31)" - assert inspect(Date.new!(-5_874_897, 1, 1)) == "Date.new!(-5874897, 1, 1)" + refute inspect(Date.new!(5_874_897, 12, 31)) == "Date.new!(5874897, 12, 31)" + refute inspect(Date.new!(-5_874_897, 1, 1)) == "Date.new!(-5874897, 1, 1)" + + assert inspect(Date.new!(5_874_897, 12, 31)) == "~D[5874897-12-31]" + assert inspect(Date.new!(-5_874_897, 1, 1)) == "~D[-5874897-01-01]" date2 = %{Date.new!(5_874_897, 12, 31) | calendar: FakeCalendar} diff --git a/lib/elixir/test/elixir/calendar/iso_test.exs b/lib/elixir/test/elixir/calendar/iso_test.exs index 6a821f50913..b9816e66e6a 100644 --- a/lib/elixir/test/elixir/calendar/iso_test.exs +++ b/lib/elixir/test/elixir/calendar/iso_test.exs @@ -51,6 +51,11 @@ defmodule Calendar.ISOTest do assert Calendar.ISO.date_to_string(10000, 1, 1, :basic) == "100000101" assert Calendar.ISO.date_to_string(10000, 1, 1, :extended) == "10000-01-01" end + + test "handles years < -9999" do + assert Calendar.ISO.date_to_string(-99_999, 1, 1, :basic) == "-999990101" + assert Calendar.ISO.date_to_string(-99_999, 1, 1, :extended) == "-99999-01-01" + end end describe "naive_datetime_to_iso_days/7" do @@ -75,6 +80,10 @@ defmodule Calendar.ISOTest do Calendar.ISO.day_of_week(2017, 11, 0, :default) end end + + test "returns the correct day of week for big years" do + assert Calendar.ISO.day_of_week(27579, 7, 13, :default) == {5, 1, 7} + end end describe "day_of_era/3" do @@ -138,12 +147,15 @@ defmodule Calendar.ISOTest do test "fails with bad data" do assert Calendar.ISO.parse_date("+201500-01-23 ") == {:error, :invalid_format} + assert Calendar.ISO.parse_date("2015y00-01-23") == {:error, :invalid_format} + assert Calendar.ISO.parse_date("201500T01-23") == {:error, :invalid_format} end end describe "parse_date/2" do test "allows enforcing basic formats" do assert Calendar.ISO.parse_date("20150123", :basic) == {:ok, {2015, 1, 23}} + assert Calendar.ISO.parse_date("20000150123", :basic) == {:error, :invalid_format} assert Calendar.ISO.parse_date("2015-01-23", :basic) == {:error, :invalid_format} end @@ -273,6 +285,9 @@ defmodule Calendar.ISOTest do assert Calendar.ISO.parse_naive_datetime("2015-01-23T23:50:07.123-02:30") == {:ok, {2015, 1, 23, 23, 50, 7, {123_000, 3}}} + assert Calendar.ISO.parse_naive_datetime("20152015-01-23T23:50:07.123+02:30") == + {:ok, {20_152_015, 1, 23, 23, 50, 7, {123_000, 3}}} + assert Calendar.ISO.parse_naive_datetime("2015-01-23T23:50:07.123-00:00") == {:error, :invalid_format} @@ -485,6 +500,7 @@ defmodule Calendar.ISOTest do assert Calendar.ISO.shift_date(2024, 1, 31, Duration.new!(month: 7)) == {2024, 8, 31} assert Calendar.ISO.shift_date(2024, 1, 31, Duration.new!(month: 8)) == {2024, 9, 30} assert Calendar.ISO.shift_date(2024, 1, 31, Duration.new!(month: 9)) == {2024, 10, 31} + assert Calendar.ISO.shift_date(2024, 1, 31, Duration.new!(year: 200_000)) == {202_024, 1, 31} end test "shift_naive_datetime/2" do From d6f79aecd19e81cf90d72c47216efafaa1e94cde Mon Sep 17 00:00:00 2001 From: Douglas Vought Date: Sat, 13 Jul 2024 05:06:18 -0400 Subject: [PATCH 4/6] Allow big years in Inspect protocol --- lib/elixir/lib/calendar/date.ex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/elixir/lib/calendar/date.ex b/lib/elixir/lib/calendar/date.ex index b9bc63e7266..99a67070662 100644 --- a/lib/elixir/lib/calendar/date.ex +++ b/lib/elixir/lib/calendar/date.ex @@ -1159,13 +1159,13 @@ defmodule Date do defimpl Inspect do def inspect(%{calendar: calendar, year: year, month: month, day: day}, _) - when year in -9999..9999 do + when calendar == Calendar.ISO do "~D[" <> calendar.date_to_string(year, month, day) <> suffix(calendar) <> "]" end def inspect(%{calendar: calendar, year: year, month: month, day: day}, _) - when calendar == Calendar.ISO do - "Date.new!(#{Integer.to_string(year)}, #{Integer.to_string(month)}, #{Integer.to_string(day)})" + when year in -9999..9999 do + "~D[" <> calendar.date_to_string(year, month, day) <> suffix(calendar) <> "]" end def inspect(%{calendar: calendar, year: year, month: month, day: day}, _) do From 44b6d0b3c0e0175428b7dd1b8f718b3e91370e6e Mon Sep 17 00:00:00 2001 From: Douglas Vought Date: Sat, 13 Jul 2024 05:46:37 -0400 Subject: [PATCH 5/6] Reorder case clauses, fix up naming --- lib/elixir/lib/calendar/iso.ex | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/elixir/lib/calendar/iso.ex b/lib/elixir/lib/calendar/iso.ex index 59f8c07efec..b0288b0bd97 100644 --- a/lib/elixir/lib/calendar/iso.ex +++ b/lib/elixir/lib/calendar/iso.ex @@ -219,11 +219,10 @@ defmodule Calendar.ISO do [match_big_year, guard_big_year, match_big_year_rest, guard_big_year_rest, read_big_year_rest] = quote do [ - <>, - y1 >= ?0 and y1 <= ?9 and (y2 >= ?0 and y2 <= ?9) and + <>, y1 >= ?0 and y1 <= ?9 and (y2 >= ?0 and y2 <= ?9) and (y3 >= ?0 and y3 <= ?9) and (y4 >= ?0 and y4 <= ?9) and (y5 >= ?0 and y5 <= ?9), <<@ext_date_sep, m1, m2, @ext_date_sep, d1, d2>>, - m1 >= ?0 and m1 <= ?9 and (m2 >= ?0 and m1 <= ?9) and (d1 >= ?0 and d1 <= ?9) and + m1 >= ?0 and m1 <= ?9 and (m2 >= ?0 and m1 <= ?9) and(d1 >= ?0 and d1 <= ?9) and (d2 >= ?0 and d2 <= ?9), { (m1 - ?0) * 10 + (m2 - ?0), @@ -443,9 +442,14 @@ defmodule Calendar.ISO do {year, rest} = parse_big_year(rest, [y5, y4, y3, y2, y1]) case parse_big_year_rest(rest) do - :error -> {:error, :invalid_format} - {{month, day}, ""} -> parse_formatted_date(year, month, day, multiplier) - {{_month, _day}, _rest} -> {:error, :invalid_format} + :error -> + {:error, :invalid_format} + + {{month, day}, ""} -> + parse_formatted_date(year, month, day, multiplier) + + {{_month, _day}, _rest} -> + {:error, :invalid_format} end end @@ -592,7 +596,7 @@ defmodule Calendar.ISO do {hour, minute, second} = unquote(read_time) parse_formatted_naive_datetime(year, month, day, hour, minute, second, rest, multiplier) - {{_month, _day}, _} -> + {{_month, _day}, _rest} -> {:error, :invalid_format} end end @@ -710,13 +714,13 @@ defmodule Calendar.ISO do :error -> {:error, :invalid_format} - {{_month, _day}, ""} -> - {:error, :invalid_format} - {{month, day}, <>} when datetime_sep in @datetime_seps and unquote(guard_time) -> {hour, minute, second} = unquote(read_time) parse_formatted_utc_datetime(year, month, day, hour, minute, second, rest, multiplier) + + {{_month, _day}, _rest} -> + {:error, :invalid_format} end end From f484be6edd988cadcfe70ff6262653104ee504d1 Mon Sep 17 00:00:00 2001 From: Douglas Vought Date: Sat, 13 Jul 2024 05:47:59 -0400 Subject: [PATCH 6/6] Format --- lib/elixir/lib/calendar/iso.ex | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/elixir/lib/calendar/iso.ex b/lib/elixir/lib/calendar/iso.ex index b0288b0bd97..f67495c4df7 100644 --- a/lib/elixir/lib/calendar/iso.ex +++ b/lib/elixir/lib/calendar/iso.ex @@ -219,10 +219,11 @@ defmodule Calendar.ISO do [match_big_year, guard_big_year, match_big_year_rest, guard_big_year_rest, read_big_year_rest] = quote do [ - <>, y1 >= ?0 and y1 <= ?9 and (y2 >= ?0 and y2 <= ?9) and + <>, + y1 >= ?0 and y1 <= ?9 and (y2 >= ?0 and y2 <= ?9) and (y3 >= ?0 and y3 <= ?9) and (y4 >= ?0 and y4 <= ?9) and (y5 >= ?0 and y5 <= ?9), <<@ext_date_sep, m1, m2, @ext_date_sep, d1, d2>>, - m1 >= ?0 and m1 <= ?9 and (m2 >= ?0 and m1 <= ?9) and(d1 >= ?0 and d1 <= ?9) and + m1 >= ?0 and m1 <= ?9 and (m2 >= ?0 and m1 <= ?9) and (d1 >= ?0 and d1 <= ?9) and (d2 >= ?0 and d2 <= ?9), { (m1 - ?0) * 10 + (m2 - ?0), @@ -442,13 +443,13 @@ defmodule Calendar.ISO do {year, rest} = parse_big_year(rest, [y5, y4, y3, y2, y1]) case parse_big_year_rest(rest) do - :error -> + :error -> {:error, :invalid_format} - - {{month, day}, ""} -> + + {{month, day}, ""} -> parse_formatted_date(year, month, day, multiplier) - - {{_month, _day}, _rest} -> + + {{_month, _day}, _rest} -> {:error, :invalid_format} end end