Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort byparts before setting defaults in iterator #337

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion build/ical.js
Original file line number Diff line number Diff line change
Expand Up @@ -6974,12 +6974,26 @@ ICAL.RecurIterator = (function() {
throw new Error("BYYEARDAY may only appear in YEARLY rules");
}


this.sort_bypart_rules("BYSECOND", parts);
this.last.second = this.setup_defaults("BYSECOND", "SECONDLY", this.dtstart.second);

this.sort_bypart_rules("BYMINUTE", parts);
this.last.minute = this.setup_defaults("BYMINUTE", "MINUTELY", this.dtstart.minute);

this.sort_bypart_rules("BYHOUR", parts);
this.last.hour = this.setup_defaults("BYHOUR", "HOURLY", this.dtstart.hour);
this.last.day = this.setup_defaults("BYMONTHDAY", "DAILY", this.dtstart.day);

this.sort_bypart_rules("BYMONTH", parts);
this.last.month = this.setup_defaults("BYMONTH", "MONTHLY", this.dtstart.month);

//setting day after month, as sorting BYMONTHDAY will differ based on the month
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If sorting bymonthday differs based on month, wouldn't we need to sort this differently every month while the rule is iteraed?

//-2 < 28 in Feb, -2 > 28 in march
this.sort_bypart_rules("BYMONTHDAY", parts);
this.last.day = this.setup_defaults("BYMONTHDAY", "DAILY", this.dtstart.day);

this.sort_bypart_rules("BYYEARDAY", parts);

if (this.rule.freq == "WEEKLY") {
if ("BYDAY" in parts) {
var bydayParts = this.ruleDayOfWeek(parts.BYDAY[0]);
Expand Down Expand Up @@ -8063,6 +8077,27 @@ ICAL.RecurIterator = (function() {
return false;
},

sort_bypart_rules: function icalrecur_sort_bypart(aPartName, aParts) {
if (aPartName in aParts) {
var offset = 0;
if (aPartName == "BYYEARDAY") {
offset = ICAL.Time.isLeapYear(this.last.year)? 367 : 366;
} else if (aPartName == "BYMONTHDAY") {
offset = ICAL.Time.daysInMonth(this.last.month, this.last.year) + 1;
}
var comparator = function(a, b) {
if (a < 0) {
a += offset;
}
if (b < 0) {
b += offset;
}
return a - b;
};
aParts[aPartName].sort(comparator);
}
},

sort_byday_rules: function icalrecur_sort_byday_rules(aRules, aWeekStart) {
for (var i = 0; i < aRules.length; i++) {
for (var j = 0; j < i; j++) {
Expand Down
2 changes: 1 addition & 1 deletion build/ical.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/ical.min.js.map

Large diffs are not rendered by default.

37 changes: 36 additions & 1 deletion lib/ical/recur_iterator.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,26 @@ ICAL.RecurIterator = (function() {
throw new Error("BYYEARDAY may only appear in YEARLY rules");
}


this.sort_bypart_rules("BYSECOND", parts);
this.last.second = this.setup_defaults("BYSECOND", "SECONDLY", this.dtstart.second);

this.sort_bypart_rules("BYMINUTE", parts);
this.last.minute = this.setup_defaults("BYMINUTE", "MINUTELY", this.dtstart.minute);

this.sort_bypart_rules("BYHOUR", parts);
this.last.hour = this.setup_defaults("BYHOUR", "HOURLY", this.dtstart.hour);
this.last.day = this.setup_defaults("BYMONTHDAY", "DAILY", this.dtstart.day);

this.sort_bypart_rules("BYMONTH", parts);
this.last.month = this.setup_defaults("BYMONTH", "MONTHLY", this.dtstart.month);

//setting day after month, as sorting BYMONTHDAY will differ based on the month
//-2 < 28 in Feb, -2 > 28 in march
this.sort_bypart_rules("BYMONTHDAY", parts);
this.last.day = this.setup_defaults("BYMONTHDAY", "DAILY", this.dtstart.day);

this.sort_bypart_rules("BYYEARDAY", parts);

if (this.rule.freq == "WEEKLY") {
if ("BYDAY" in parts) {
var bydayParts = this.ruleDayOfWeek(parts.BYDAY[0]);
Expand Down Expand Up @@ -1300,6 +1314,27 @@ ICAL.RecurIterator = (function() {
return false;
},

sort_bypart_rules: function icalrecur_sort_bypart(aPartName, aParts) {
if (aPartName in aParts) {
var offset = 0;
if (aPartName == "BYYEARDAY") {
offset = ICAL.Time.isLeapYear(this.last.year)? 367 : 366;
} else if (aPartName == "BYMONTHDAY") {
offset = ICAL.Time.daysInMonth(this.last.month, this.last.year) + 1;
}
var comparator = function(a, b) {
if (a < 0) {
a += offset;
}
if (b < 0) {
b += offset;
}
return a - b;
};
aParts[aPartName].sort(comparator);
}
},

sort_byday_rules: function icalrecur_sort_byday_rules(aRules, aWeekStart) {
for (var i = 0; i < aRules.length; i++) {
for (var j = 0; j < i; j++) {
Expand Down
113 changes: 113 additions & 0 deletions test/recur_iterator_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,17 @@ suite('recur_iterator', function() {
]
});

//secondly + unsorted bysecond
testRRULE('FREQ=SECONDLY;BYSECOND=3,2,1;UNTIL=20130101T000003Z', {
dtStart: '2013-01-01T00:00:01',
until: true,
dates: [
'2013-01-01T00:00:01',
'2013-01-01T00:00:02',
'2013-01-01T00:00:03'
]
});

// Simple minutely
testRRULE('FREQ=MINUTELY;INTERVAL=3;COUNT=3', {
byCount: true,
Expand All @@ -253,6 +264,16 @@ suite('recur_iterator', function() {
]
});

//minutely + unsorted byminute
testRRULE('FREQ=MINUTELY;BYMINUTE=3,2,1;UNTIL=20130101T000200Z', {
dtStart: '2013-01-01T00:01:00',
until: true,
dates: [
'2013-01-01T00:01:00',
'2013-01-01T00:02:00'
]
});

//simple hourly
testRRULE('FREQ=HOURLY;INTERVAL=3;COUNT=3', {
byCount: true,
Expand All @@ -262,6 +283,16 @@ suite('recur_iterator', function() {
'2015-04-30T14:00:00'
]
});

//hourly + unsorted byhour
testRRULE('FREQ=HOURLY;BYHOUR=3,2,1;UNTIL=20130101T020000Z', {
dtStart: '2013-01-01T01:00:00',
until: true,
dates: [
'2013-01-01T01:00:00',
'2013-01-01T02:00:00'
]
});
});

suite('DAILY', function() {
Expand Down Expand Up @@ -687,6 +718,27 @@ suite('recur_iterator', function() {
]
});

//monthly + unsorted bymonthday
testRRULE('FREQ=MONTHLY;BYMONTHDAY=3,2,1;UNTIL=20130102T000000Z', {
dtStart: '2013-01-01',
until: true,
dates: [
'2013-01-01',
'2013-01-02'
]
});

//monthly + unsorted bymonth
testRRULE('FREQ=MONTHLY;BYMONTH=3,2,1;UNTIL=20130301T000000Z', {
dtStart: '2013-01-01',
until: true,
dates: [
'2013-01-01',
'2013-02-01',
'2013-03-01'
]
});

testRRULE('FREQ=MONTHLY;BYDAY=MO,FR;BYMONTHDAY=1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31;COUNT=4', {
dtStart: '2015-03-01T08:00:00Z',
byCount: true,
Expand Down Expand Up @@ -732,6 +784,37 @@ suite('recur_iterator', function() {
"2015-04-19T08:00:00Z"
]
})

//monthly + unsorted positive, negative bymonthday
testRRULE('FREQ=MONTHLY;BYMONTHDAY=-1,1;UNTIL=20130201T000000Z', {
dtStart: '2013-01-01',
until: true,
dates: [
'2013-01-01',
'2013-01-31',
'2013-02-01'
]
});

//monthly + unsorted positive, negative bymonthday
testRRULE('FREQ=MONTHLY;BYMONTHDAY=28,-2;UNTIL=20130227T000000Z', {
dtStart: '2013-02-25',
until: true,
dates: [
'2013-02-27'
]
});

//monthly + unsorted positive, negative bymonthday
testRRULE('FREQ=MONTHLY;BYMONTHDAY=31,-2;UNTIL=20130427T000000Z', {
dtStart: '2013-02-25',
until: true,
dates: [
'2013-02-27',
'2013-03-30',
'2013-03-31',
]
});
});

suite('YEARLY', function() {
Expand Down Expand Up @@ -984,6 +1067,36 @@ suite('recur_iterator', function() {
]
});

//yearly + unsorted bymonth
testRRULE('FREQ=YEARLY;BYMONTH=3,2,1;UNTIL=20130201T000000Z', {
dtStart: '2013-01-01',
until: true,
dates: [
'2013-01-01',
'2013-02-01'
]
});

//yearly + unsorted byyearday
testRRULE('FREQ=YEARLY;BYYEARDAY=3,2,1;UNTIL=20130102T000000Z', {
dtStart: '2013-01-01',
until: true,
dates: [
'2013-01-01',
'2013-01-02'
]
});

//yearly + unsorted positive, negative bymonthday
testRRULE('FREQ=YEARLY;BYMONTH=3;BYMONTHDAY=-2,28;UNTIL=20130330T000000Z', {
dtStart: '2013-02-25',
until: true,
dates: [
'2013-03-28',
'2013-03-30',
]
});

/*
* Leap-year test for February 29th
*
Expand Down