Skip to content

Commit 46ff55f

Browse files
committed
Use date helper to inflate months and years
1 parent 8a3a325 commit 46ff55f

File tree

2 files changed

+182
-5
lines changed

2 files changed

+182
-5
lines changed

lib/recurring_events/by_pump.ex

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,25 @@ defmodule RecurringEvents.ByPump do
6262
defp inflate_week(date, rules) do
6363
week_start = week_start_date(date, rules)
6464
week_end = week_end_date(date, rules)
65+
6566
inflate_period(week_start, week_end)
6667
end
6768

6869
defp inflate_month(date) do
69-
month_start = %{date | day: 1}
70-
month_end = %{date | day: @date_helper.last_day_of_the_month(date)}
70+
start_shift = 1 - date.day
71+
end_shift = @date_helper.last_day_of_the_month(date) -1
72+
73+
month_start = @date_helper.shift_date(date, start_shift, :days)
74+
month_end = @date_helper.shift_date(month_start, end_shift, :days)
7175
inflate_period(month_start, month_end)
7276
end
7377

7478
defp inflate_year(date) do
75-
year_start = %{date | day: 1, month: 1}
76-
year_end = %{date | day: 31, month: 12}
79+
start_shift = 1 - @date_helper.day_of_the_year(date)
80+
end_shift = @date_helper.last_day_of_the_year(date) - 1
81+
82+
year_start = @date_helper.shift_date(date, start_shift, :days)
83+
year_end = @date_helper.shift_date(year_start, end_shift, :days)
7784
inflate_period(year_start, year_end)
7885
end
7986

test/timezone_test.exs

Lines changed: 171 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
defmodule RecurringEvents.TimezoneTest do
22
use ExUnit.Case, async: true
33
import RecurringEvents.TestHelper
4+
alias RecurringEvents, as: RR
45

56
if Code.ensure_loaded?(Timex) do
67
test "should handle timezones if Timex available" do
78
time = Timex.to_datetime({{2018, 11, 2}, {5, 0, 0}}, "America/Los_Angeles")
89

910
result =
10-
RecurringEvents.take(
11+
RR.take(
1112
time,
1213
%{freq: :daily, by_hour: 3, by_minute: 0, by_second: 0},
1314
5
@@ -20,6 +21,168 @@ defmodule RecurringEvents.TimezoneTest do
2021
)
2122
end
2223

24+
@doc """
25+
Every other week - forever
26+
27+
DTSTART;TZID=US-Eastern:19970902T090000
28+
RRULE:FREQ=WEEKLY;INTERVAL=2;WKST=SU
29+
30+
==> (1997 9:00 AM EDT)September 2,16,30;October 14
31+
(1997 9:00 AM EST)October 28;November 11,25;December 9,23
32+
(1998 9:00 AM EST)January 6,20;February
33+
...
34+
"""
35+
test "Every other week - forever" do
36+
result =
37+
Timex.to_datetime({1997, 9, 2}, "America/Los_Angeles")
38+
|> RR.unfold(%{freq: :weekly, interval: 2, week_start: :sunday})
39+
40+
expect =
41+
date_tz_expand(
42+
[
43+
{1997, 9, [2, 16, 30]},
44+
{1997, 10, [14, 28]},
45+
{1997, 11, [11, 25]},
46+
{1997, 12, [9, 23]},
47+
{1998, 1, [6, 20]}
48+
],
49+
"America/Los_Angeles"
50+
)
51+
52+
assert expect == result |> Enum.take(expect |> Enum.count())
53+
end
54+
55+
@doc """
56+
Every other month on the 1st and last Sunday of the month for 10
57+
occurrences:
58+
59+
DTSTART;TZID=US-Eastern:19970907T090000
60+
RRULE:FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=1SU,-1SU
61+
62+
==> (1997 9:00 AM EDT)September 7,28
63+
(1997 9:00 AM EST)November 2,30
64+
(1998 9:00 AM EST)January 4,25;March 1,29
65+
(1998 9:00 AM EDT)May 3,31
66+
"""
67+
test "Every other month on the 1st and last Sunday of the month for 10 occurrences" do
68+
result =
69+
Timex.to_datetime({1997, 9, 7}, "America/Los_Angeles")
70+
|> RR.unfold(%{
71+
freq: :monthly,
72+
interval: 2,
73+
count: 10,
74+
by_day: [{1, :sunday}, {-1, :sunday}]
75+
})
76+
77+
expect =
78+
date_tz_expand(
79+
[
80+
{1997, 9, [7, 28]},
81+
{1997, 11, [2, 30]},
82+
{1998, 1, [4, 25]},
83+
{1998, 3, [1, 29]},
84+
{1998, 5, [3, 31]}
85+
],
86+
"America/Los_Angeles"
87+
)
88+
89+
assert expect == result |> Enum.take(999)
90+
end
91+
92+
@doc """
93+
Weekly until December 24, 1997
94+
95+
DTSTART;TZID=US-Eastern:19970902T090000
96+
RRULE:FREQ=WEEKLY;UNTIL=19971224T000000Z
97+
98+
==> (1997 9:00 AM EDT)September 2,9,16,23,30;October 7,14,21
99+
(1997 9:00 AM EST)October 28;November 4,11,18,25;
100+
December 2,9,16,23
101+
"""
102+
test "Weekly until December 24, 1997" do
103+
result =
104+
Timex.to_datetime({1997, 9, 2}, "America/Los_Angeles")
105+
|> RR.unfold(%{
106+
freq: :weekly,
107+
until: Timex.to_datetime({1997, 12, 24}, "America/Los_Angeles")
108+
})
109+
110+
expect =
111+
date_tz_expand(
112+
[
113+
{1997, 9, [2, 9, 16, 23, 30]},
114+
{1997, 10, [7, 14, 21, 28]},
115+
{1997, 11, [4, 11, 18, 25]},
116+
{1997, 12, [2, 9, 16, 23]}
117+
],
118+
"America/Los_Angeles"
119+
)
120+
121+
assert expect == result |> Enum.take(999)
122+
end
123+
124+
@doc """
125+
Weekly for 10 occurrences
126+
127+
DTSTART;TZID=US-Eastern:19970902T090000
128+
RRULE:FREQ=WEEKLY;COUNT=10
129+
130+
==> (1997 9:00 AM EDT)September 2,9,16,23,30;October 7,14,21
131+
(1997 9:00 AM EST)October 28;November 4
132+
"""
133+
test "Weekly for 10 occurrences" do
134+
result =
135+
Timex.to_datetime({1997, 9, 2}, "America/Los_Angeles")
136+
|> RR.unfold(%{freq: :weekly, count: 10})
137+
138+
expect =
139+
date_tz_expand(
140+
[
141+
{1997, 9, [2, 9, 16, 23, 30]},
142+
{1997, 10, [7, 14, 21, 28]},
143+
{1997, 11, 4}
144+
],
145+
"America/Los_Angeles"
146+
)
147+
148+
assert expect == result |> Enum.take(999)
149+
end
150+
151+
@doc """
152+
Monthly on the first and last day of the month for 10 occurrences
153+
154+
DTSTART;TZID=US-Eastern:19970930T090000
155+
RRULE:FREQ=MONTHLY;COUNT=10;BYMONTHDAY=1,-1
156+
157+
==> (1997 9:00 AM EDT)September 30;October 1
158+
(1997 9:00 AM EST)October 31;November 1,30;December 1,31
159+
(1998 9:00 AM EST)January 1,31;February 1
160+
"""
161+
test "Monthly on the first and last day of the month for 10 occurrences" do
162+
result =
163+
Timex.to_datetime({1997, 9, 30}, "America/Los_Angeles")
164+
|> RR.unfold(%{
165+
freq: :monthly,
166+
count: 10,
167+
by_month_day: [1, -1]
168+
})
169+
170+
expect =
171+
date_tz_expand(
172+
[
173+
{1997, 9, 30},
174+
{1997, 10, [1, 31]},
175+
{1997, 11, [1, 30]},
176+
{1997, 12, [1, 31]},
177+
{1998, 1, [1, 31]},
178+
{1998, 2, 1}
179+
],
180+
"America/Los_Angeles"
181+
)
182+
183+
assert expect == result |> Enum.take(999)
184+
end
185+
23186
def date_tz_expand(date_list, time_zone) when is_list(date_list) do
24187
Enum.flat_map(date_list, fn t -> date_tz_expand(t, time_zone) end)
25188
end
@@ -33,5 +196,12 @@ defmodule RecurringEvents.TimezoneTest do
33196
second <- listify(seconds),
34197
do: Timex.to_datetime({{year, month, day}, {hour, minute, second}}, time_zone)
35198
end
199+
200+
def date_tz_expand({years, months, days}, time_zone) do
201+
for year <- listify(years),
202+
month <- listify(months),
203+
day <- listify(days),
204+
do: Timex.to_datetime({year, month, day}, time_zone)
205+
end
36206
end
37207
end

0 commit comments

Comments
 (0)