Skip to content

Commit 7650afb

Browse files
support Duration in Date.range/3
1 parent ef1450d commit 7650afb

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

lib/elixir/lib/calendar/date.ex

+12-2
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ defmodule Date do
100100
101101
"""
102102
@doc since: "1.5.0"
103-
@spec range(Calendar.date(), Calendar.date()) :: Date.Range.t()
103+
@spec range(Calendar.date(), Calendar.date() | Duration.t()) :: Date.Range.t()
104104
def range(%{calendar: calendar} = first, %{calendar: calendar} = last) do
105105
{first_days, _} = to_iso_days(first)
106106
{last_days, _} = to_iso_days(last)
@@ -119,6 +119,11 @@ defmodule Date do
119119
range(first, first_days, last, last_days, calendar, step)
120120
end
121121

122+
def range(%{calendar: calendar} = first, %Duration{} = duration) do
123+
last = shift(first, duration)
124+
range(first, last)
125+
end
126+
122127
def range(%{calendar: _, year: _, month: _, day: _}, %{calendar: _, year: _, month: _, day: _}) do
123128
raise ArgumentError, "both dates must have matching calendars"
124129
end
@@ -140,7 +145,7 @@ defmodule Date do
140145
141146
"""
142147
@doc since: "1.12.0"
143-
@spec range(Calendar.date(), Calendar.date(), step :: pos_integer | neg_integer) ::
148+
@spec range(Calendar.date(), Calendar.date() | Duration.t(), step :: pos_integer | neg_integer) ::
144149
Date.Range.t()
145150
def range(%{calendar: calendar} = first, %{calendar: calendar} = last, step)
146151
when is_integer(step) and step != 0 do
@@ -149,6 +154,11 @@ defmodule Date do
149154
range(first, first_days, last, last_days, calendar, step)
150155
end
151156

157+
def range(%{calendar: calendar} = first, %Duration{} = duration, step) do
158+
last = shift(first, duration)
159+
range(first, last, step)
160+
end
161+
152162
def range(
153163
%{calendar: _, year: _, month: _, day: _} = first,
154164
%{calendar: _, year: _, month: _, day: _} = last,

lib/elixir/test/elixir/calendar/date_range_test.exs

+22
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ defmodule Date.RangeTest do
66

77
@asc_range Date.range(~D[2000-01-01], ~D[2001-01-01])
88
@asc_range_2 Date.range(~D[2000-01-01], ~D[2001-01-01], 2)
9+
@asc_range_duration Date.range(~D[2000-01-01], Duration.new!(year: 1))
10+
@asc_range_duration_2 Date.range(~D[2000-01-01], Duration.new!(year: 1), 2)
911
@desc_range Date.range(~D[2001-01-01], ~D[2000-01-01], -1)
1012
@desc_range_2 Date.range(~D[2001-01-01], ~D[2000-01-01], -2)
13+
@desc_range_duration Date.range(~D[2001-01-01], Duration.new!(year: -1))
14+
@desc_range_duration_2 Date.range(~D[2001-01-01], Duration.new!(year: -1), 2)
1115
@empty_range Date.range(~D[2001-01-01], ~D[2000-01-01], 1)
1216

1317
describe "Enum.member?/2" do
@@ -20,6 +24,9 @@ defmodule Date.RangeTest do
2024

2125
assert Enum.member?(@asc_range_2, ~D[2000-01-03])
2226
refute Enum.member?(@asc_range_2, ~D[2000-01-02])
27+
28+
assert Enum.member?(@asc_range_duration, ~D[2000-01-03])
29+
refute Enum.member?(@asc_range_duration_2, ~D[2000-01-02])
2330
end
2431

2532
test "for descending range" do
@@ -31,6 +38,9 @@ defmodule Date.RangeTest do
3138

3239
assert Enum.member?(@desc_range_2, ~D[2000-12-30])
3340
refute Enum.member?(@desc_range_2, ~D[2000-12-29])
41+
42+
assert Enum.member?(@desc_range_duration, ~D[2000-12-30])
43+
refute Enum.member?(@desc_range_duration_2, ~D[2000-12-29])
3444
end
3545

3646
test "empty range" do
@@ -109,6 +119,18 @@ defmodule Date.RangeTest do
109119
assert Enum.to_list(range) == [~D[2000-01-01], ~D[2000-01-03]]
110120
end
111121

122+
test "works with durations" do
123+
range = Date.range(~D[2000-01-01], Duration.new!(day: 1))
124+
assert range.first == ~D[2000-01-01]
125+
assert range.last == ~D[2000-01-02]
126+
assert Enum.to_list(range) == [~D[2000-01-01], ~D[2000-01-02]]
127+
128+
range = Date.range(~D[2000-01-01], Duration.new!(day: 2), 2)
129+
assert range.first == ~D[2000-01-01]
130+
assert range.last == ~D[2000-01-03]
131+
assert Enum.to_list(range) == [~D[2000-01-01], ~D[2000-01-03]]
132+
end
133+
112134
test "both dates must have matching calendars" do
113135
first = ~D[2000-01-01]
114136
last = Calendar.Holocene.date(12001, 1, 1)

0 commit comments

Comments
 (0)