Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

fix another end of month error

  • Loading branch information...
commit 5676954b4e1e6655dc2f213d9d398c87519cf769 1 parent 677839b
@bakineggs bakineggs authored
View
10 generate_recurrences.sql
@@ -1,5 +1,6 @@
CREATE OR REPLACE FUNCTION generate_recurrences(
duration INTERVAL,
+ original_date DATE,
range_start DATE,
range_end DATE,
repeat_month INT,
@@ -10,9 +11,9 @@ CREATE OR REPLACE FUNCTION generate_recurrences(
LANGUAGE plpgsql IMMUTABLE
AS $BODY$
DECLARE
- start_date DATE := range_start;
+ start_date DATE := original_date;
next_date DATE;
- intervals INT := 0;
+ intervals INT := FLOOR(intervals_between(original_date, range_start, duration));
current_month INT;
current_week INT;
BEGIN
@@ -26,8 +27,8 @@ BEGIN
start_date := start_date + (repeat_day - extract(day from start_date) || ' days')::interval;
END IF;
END IF;
- next_date := start_date;
LOOP
+ next_date := start_date + duration * intervals;
IF repeat_week IS NOT NULL AND repeat_day IS NOT NULL THEN
current_month := extract(month from next_date);
next_date := next_date + (((7 + repeat_day - cast(extract(dow from next_date) as int)) % 7) || ' days')::interval;
@@ -42,11 +43,10 @@ BEGIN
next_date := next_date + (repeat_week - current_week) * '7 days'::interval;
END IF;
EXIT WHEN next_date > range_end;
- IF next_date >= range_start THEN
+ IF next_date >= range_start AND next_date >= original_date THEN
RETURN NEXT next_date;
END IF;
intervals := intervals + 1;
- next_date := start_date + duration * intervals;
END LOOP;
END;
$BODY$;
View
5 recurrences_for.sql
@@ -20,10 +20,6 @@ BEGIN
recurrences_end := recurrences_start + (event.count - 1) * duration;
END IF;
- IF range_start > recurrences_start THEN
- recurrences_start := recurrences_start + FLOOR(intervals_between(recurrences_start, range_start::date, duration)) * duration;
- END IF;
-
FOR recurrence IN
SELECT event_recurrences.*
FROM (SELECT NULL) AS foo
@@ -35,6 +31,7 @@ BEGIN
FROM generate_recurrences(
duration,
recurrences_start,
+ range_start::date,
recurrences_end,
recurrence.month,
recurrence.week,
View
2  recurring_events_for.sql
@@ -39,7 +39,7 @@ BEGIN
duration := event.ends_at - event.starts_at;
END IF;
- IF event.count IS NOT NULL AND recurrences_start > original_date THEN
+ IF event.count IS NOT NULL THEN
recurrences_start := original_date;
END IF;
View
24 spec/generate_recurrences_spec.rb
@@ -2,7 +2,7 @@
describe 'generate_recurrences' do
it "should return dates inside of the range" do
- executing("select * from generate_recurrences('1 day', '2008-04-25', '2008-04-29', NULL, NULL, NULL);").should == [
+ executing("select * from generate_recurrences('1 day', '2008-04-20', '2008-04-25', '2008-04-29', NULL, NULL, NULL);").should == [
['2008-04-25'],
['2008-04-26'],
['2008-04-27'],
@@ -12,7 +12,7 @@
end
it "should only include dates on the frequency specified" do
- executing("select * from generate_recurrences('7 days', '2008-04-01', '2008-04-29', NULL, NULL, NULL);").should == [
+ executing("select * from generate_recurrences('7 days', '2008-04-01', '2008-04-01', '2008-04-29', NULL, NULL, NULL);").should == [
['2008-04-01'],
['2008-04-08'],
['2008-04-15'],
@@ -22,7 +22,7 @@
end
it "should return dates on the correct day of month when the start is the end of the month" do
- executing("select * from generate_recurrences('1 month', '2008-05-31', '2008-07-31', NULL, NULL, NULL);").should == [
+ executing("select * from generate_recurrences('1 month', '2008-05-31', '2008-05-31', '2008-07-31', NULL, NULL, NULL);").should == [
['2008-05-31'],
['2008-06-30'],
['2008-07-31']
@@ -31,7 +31,7 @@
describe 'by day of week' do
it "should return dates on the requested day of week" do
- executing("select * from generate_recurrences('7 days', '2008-05-12', '2008-05-23', NULL, NULL, 4);").should == [
+ executing("select * from generate_recurrences('7 days', '2008-05-12', '2008-05-12', '2008-05-23', NULL, NULL, 4);").should == [
['2008-05-15'],
['2008-05-22']
]
@@ -40,7 +40,7 @@
describe 'by month' do
it "should return the day in the requested month" do
- executing("select * from generate_recurrences('1 year', '2008-04-15', '2010-06-15', 5, NULL, NULL);").should == [
+ executing("select * from generate_recurrences('1 year', '2008-04-15', '2008-04-15', '2010-06-15', 5, NULL, NULL);").should == [
['2008-05-15'],
['2009-05-15'],
['2010-05-15']
@@ -50,7 +50,7 @@
describe 'by day of month' do
it "should return the dates on the requested day of month" do
- executing("select * from generate_recurrences('1 month', '2008-04-01', '2008-06-30', NULL, NULL, 15);").should == [
+ executing("select * from generate_recurrences('1 month', '2008-04-01', '2008-04-01', '2008-06-30', NULL, NULL, 15);").should == [
['2008-04-15'],
['2008-05-15'],
['2008-06-15']
@@ -59,7 +59,7 @@
describe 'by month' do
it "should return the correct day of month in the correct month" do
- executing("select * from generate_recurrences('1 year', '2008-04-01', '2010-06-30', 5, NULL, 15);").should == [
+ executing("select * from generate_recurrences('1 year', '2008-04-01', '2008-04-01', '2010-06-30', 5, NULL, 15);").should == [
['2008-05-15'],
['2009-05-15'],
['2010-05-15']
@@ -70,7 +70,7 @@
describe 'by week and day of week' do
it "should include the dates on the particular positive offset week's day of week" do
- executing("select * from generate_recurrences('1 month', '2008-04-01', '2008-06-30', NULL, 3, 2);").should == [
+ executing("select * from generate_recurrences('1 month', '2008-04-01', '2008-04-01', '2008-06-30', NULL, 3, 2);").should == [
['2008-04-15'],
['2008-05-20'],
['2008-06-17']
@@ -78,7 +78,7 @@
end
it "should include the dates on the particular negative offset week's day of week" do
- executing("select * from generate_recurrences('1 month', '2008-04-01', '2008-06-30', NULL, -2, 4);").should == [
+ executing("select * from generate_recurrences('1 month', '2008-04-01', '2008-04-01', '2008-06-30', NULL, -2, 4);").should == [
['2008-04-17'],
['2008-05-22'],
['2008-06-19']
@@ -86,7 +86,7 @@
end
it "should not skip a month if offsetting to the correct day of week puts us in the wrong month" do
- executing("select * from generate_recurrences('1 month', '2008-05-01', '2008-07-31', NULL, -1, 5);").should == [
+ executing("select * from generate_recurrences('1 month', '2008-05-01', '2008-05-01', '2008-07-31', NULL, -1, 5);").should == [
['2008-05-30'],
['2008-06-27'],
['2008-07-25']
@@ -94,7 +94,7 @@
end
it "should return the correct week when the event should repeat on the last day of the month and the next month has fewer days" do
- executing("select * from generate_recurrences('1 month', '2008-04-26', '2008-06-28', NULL, -1, 6);").should == [
+ executing("select * from generate_recurrences('1 month', '2008-04-26', '2008-04-26', '2008-06-28', NULL, -1, 6);").should == [
['2008-04-26'],
['2008-05-31'],
['2008-06-28']
@@ -103,7 +103,7 @@
describe 'by month' do
it "should return the dates in the correct month" do
- executing("select * from generate_recurrences('1 year', '2008-04-01', '2010-06-30', 5, 3, 2);").should == [
+ executing("select * from generate_recurrences('1 year', '2008-04-01', '2008-04-01', '2010-06-30', 5, 3, 2);").should == [
['2008-05-20'],
['2009-05-19'],
['2010-05-18']
View
10 spec/recurring_events_for_spec.rb
@@ -380,6 +380,16 @@
]
end
+ it "should maintain the day of month for events at the end of the month" do
+ executing([
+ "insert into events (date, frequency) values ('2008-05-31', 'monthly');",
+ "select date from recurring_events_for('2008-06-30 12:00pm', '2008-08-01 12:00pm', 'UTC', NULL);"
+ ]).should == [
+ ['2008-06-30'],
+ ['2008-07-31']
+ ]
+ end
+
describe 'using a custom day of month' do
it "should include the event on the specified days" do
executing([
Please sign in to comment.
Something went wrong with that request. Please try again.