Skip to content

Commit 52c993a

Browse files
committed
Ensure Julian.* calendars round trip
1 parent 043f287 commit 52c993a

File tree

9 files changed

+65
-2
lines changed

9 files changed

+65
-2
lines changed

lib/cldr/calendar/calendars/julian_compiler.ex

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
defmodule Cldr.Calendar.Julian.Compiler do
2+
# See https://stevemorse.org/jcal/julian.html
23

34
defmacro __before_compile__(env) do
45
opts =
@@ -21,6 +22,13 @@ defmodule Cldr.Calendar.Julian.Compiler do
2122

2223
defguard year_rollover(month, day) when month <= @new_year_starting_month and day < @new_year_starting_day
2324

25+
# Adjust the year to be a Jan 1st starting year and carry
26+
# on
27+
28+
def date_to_iso_days(year, month, day) when year_rollover(month, day) do
29+
Cldr.Calendar.Julian.date_to_iso_days(year + 1, month, day)
30+
end
31+
2432
def date_to_iso_days(year, month, day) do
2533
Cldr.Calendar.Julian.date_to_iso_days(year, month, day)
2634
end
@@ -34,12 +42,17 @@ defmodule Cldr.Calendar.Julian.Compiler do
3442
{year, month, day} = Cldr.Calendar.Julian.date_from_iso_days(iso_days)
3543

3644
if month <= @new_year_starting_month and day < @new_year_starting_day do
37-
{year + 1, month, day}
45+
{year - 1, month, day}
3846
else
3947
{year, month, day}
4048
end
4149
end
4250

51+
def naive_datetime_from_iso_days({iso_days, _}) do
52+
{year, month, day} = date_from_iso_days(iso_days)
53+
{year, month, day, 0, 0, 0, {0, 0}}
54+
end
55+
4356
def days_in_year(year) do
4457
first_day = date_to_iso_days(year, @new_year_starting_month, @new_year_starting_day)
4558
first_day_next_year = date_to_iso_days(year + 1, @new_year_starting_month, @new_year_starting_day)
@@ -195,7 +208,6 @@ defmodule Cldr.Calendar.Julian.Compiler do
195208
defdelegate shift_naive_datetime(year, month, day, hour, minute, second, millisecond, duration), to: Cldr.Calendar.Julian
196209
defdelegate iso_days_to_end_of_day(iso_days), to: Cldr.Calendar.Julian
197210
defdelegate iso_days_to_beginning_of_day(iso_days), to: Cldr.Calendar.Julian
198-
defdelegate naive_datetime_from_iso_days(iso_days), to: Cldr.Calendar.Julian
199211
defdelegate parse_utc_datetime(string), to: Cldr.Calendar.Julian
200212
defdelegate parse_time(string), to: Cldr.Calendar.Julian
201213
defdelegate parse_naive_datetime(string), to: Cldr.Calendar.Julian
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
defmodule Cldr.Calendar.Julian.Dec25 do
2+
use Cldr.Calendar.Julian, new_year_starting_month_and_day: {12, 25}
3+
4+
end
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
defmodule Cldr.Calendar.Julian.Jan1 do
2+
use Cldr.Calendar.Julian, new_year_starting_month_and_day: {1, 1}
3+
4+
end
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
defmodule Cldr.Calendar.Julian.March1 do
2+
use Cldr.Calendar.Julian, new_year_starting_month_and_day: {3, 1}
3+
4+
end
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
defmodule Cldr.Calendar.Julian.March25 do
2+
use Cldr.Calendar.Julian, new_year_starting_month_and_day: {3, 25}
3+
4+
end
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
defmodule Cldr.Calendar.Julian.Sept1 do
2+
use Cldr.Calendar.Julian, new_year_starting_month_and_day: {9, 1}
3+
4+
end

test/julian_calendar_test.exs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,24 @@ defmodule Cldr.Calendar.Julian.Test do
99
test "plus years in a Julian date" do
1010
assert Cldr.Calendar.Julian.plus(1, 1, 1, :years, 1)
1111
end
12+
13+
test "Calendar conversion from Julian starting March 25 for dates before new year" do
14+
assert {:ok, ~D[1751-01-12 Cldr.Calendar.Gregorian]} ==
15+
Date.convert(~D[1750-01-01 Cldr.Calendar.Julian.March25], Cldr.Calendar.Gregorian)
16+
end
17+
18+
test "Calendar conversion from Julian starting March 25 for dates after new year" do
19+
assert {:ok, ~D[1751-04-05 Cldr.Calendar.Gregorian]} ==
20+
Date.convert(~D[1751-03-25 Cldr.Calendar.Julian.March25], Cldr.Calendar.Gregorian)
21+
end
22+
23+
test "Calendar conversion to Julian starting March 25 for dates before new year" do
24+
assert {:ok, ~D[1750-01-01 Cldr.Calendar.Julian.March25]} ==
25+
Date.convert(~D[1751-01-12 Cldr.Calendar.Gregorian], Cldr.Calendar.Julian.March25)
26+
end
27+
28+
test "Calendar conversion to Julian starting March 25 for dates after new year" do
29+
assert {:ok, ~D[1751-03-25 Cldr.Calendar.Julian.March25]} ==
30+
Date.convert(~D[1751-04-05 Cldr.Calendar.Gregorian], Cldr.Calendar.Julian.March25)
31+
end
1232
end

test/round_trip_test.exs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,17 @@ defmodule Cldr.Calendar.RoundTrip.Test do
8787
end
8888
end
8989

90+
test "that Cldr.Calendar.Julian.March25 dates all round trip" do
91+
for year <- 0001..1800,
92+
month <- 1..12,
93+
day <- 1..28 do
94+
{:ok, julian} = Date.new(year, month, day, Cldr.Calendar.Julian.March25)
95+
{:ok, iso} = Date.convert(julian, Calendar.ISO)
96+
{:ok, converted} = Date.convert(iso, Cldr.Calendar.Julian.March25)
97+
assert Date.compare(julian, converted) == :eq
98+
end
99+
end
100+
90101
if function_exported?(Code, :fetch_docs, 1) do
91102
test "that no module docs are generated for a backend" do
92103
assert {:docs_v1, _, :elixir, _, :hidden, %{}, _} = Code.fetch_docs(NoDocs.Cldr.Calendar)

test/support/julian_calendars.ex

Whitespace-only changes.

0 commit comments

Comments
 (0)