@interface iCalDailyRecurrenceCalculator : iCalRecurrenceCalculator
{
}
-- (unsigned)factor;
@end
-@interface iCalWeeklyRecurrenceCalculator : iCalDailyRecurrenceCalculator
+@interface iCalWeeklyRecurrenceCalculator : iCalRecurrenceCalculator
{
}
@end
jnRuleLast = [until julianNumber];
}
else {
- jnRuleLast = (interval * [self->rrule repeatCount] * [self factor])
+ jnRuleLast = (interval * [self->rrule repeatCount])
+ jnFirst;
if (jnRuleLast < jnStart)
return nil;
jnEnd = jnRuleLast;
}
- ranges = [NSMutableArray arrayWithCapacity:5];
startEndCount = (jnEnd - jnStart) + 1;
+ ranges = [NSMutableArray arrayWithCapacity:startEndCount];
for (i = 0 ; i < startEndCount; i++) {
- long jnTest;
-
- jnTest = (jnStart + i) - jnFirst;
- if ((jnTest % interval) == 0) {
- NSCalendarDate *start, *end;
- NGCalendarDateRange *r;
+ long jnCurrent;
- start = [NSCalendarDate dateForJulianNumber:jnStart + i];
- start = [start hour: [firStart hourOfDay]
- minute:[firStart minuteOfHour]
- second:[firStart secondOfMinute]];
- end = [start addTimeInterval:[self->firstRange duration]];
- r = [NGCalendarDateRange calendarDateRangeWithStartDate:start
- endDate:end];
- [ranges addObject:r];
+ jnCurrent = jnStart + i;
+ if (jnCurrent >= jnFirst) {
+ long jnTest;
+
+ jnTest = jnCurrent - jnFirst;
+ if ((jnTest % interval) == 0) {
+ NSCalendarDate *start, *end;
+ NGCalendarDateRange *r;
+
+ start = [NSCalendarDate dateForJulianNumber:jnCurrent];
+ start = [start hour: [firStart hourOfDay]
+ minute:[firStart minuteOfHour]
+ second:[firStart secondOfMinute]];
+ end = [start addTimeInterval:[self->firstRange duration]];
+ r = [NGCalendarDateRange calendarDateRangeWithStartDate:start
+ endDate:end];
+ [ranges addObject:r];
+ }
}
}
-
return ranges;
}
firStart = [self->firstRange startDate];
jnFirst = [firStart julianNumber];
jnRuleLast = ([self->rrule repeatInterval] *
- [self->rrule repeatCount] *
- [self factor]) +
+ [self->rrule repeatCount]) +
jnFirst;
until = [NSCalendarDate dateForJulianNumber:jnRuleLast];
until = [until hour: [firStart hourOfDay]
return [super lastInstanceStartDate];
}
-- (unsigned)factor {
- return 1;
-}
-
@end /* iCalDailyRecurrenceCalculator */
*/
@implementation iCalWeeklyRecurrenceCalculator
-- (unsigned)factor {
- return 7;
+- (NSArray *)recurrenceRangesWithinCalendarDateRange:(NGCalendarDateRange *)_r {
+ NSMutableArray *ranges;
+ NSCalendarDate *firStart;
+ long i, jnFirst, jnStart, jnEnd, startEndCount;
+ unsigned interval, byDayMask;
+
+ firStart = [self->firstRange startDate];
+ jnFirst = [firStart julianNumber];
+ jnEnd = [[_r endDate] julianNumber];
+
+ if (jnFirst > jnEnd)
+ return nil;
+
+ jnStart = [[_r startDate] julianNumber];
+ interval = [self->rrule repeatInterval];
+
+ /* if rule is bound, check the bounds */
+ if (![self->rrule isInfinite]) {
+ NSCalendarDate *until;
+ long jnRuleLast;
+
+ until = [self->rrule untilDate];
+ if (until) {
+ if ([until compare:[_r startDate]] == NSOrderedAscending)
+ return nil;
+ jnRuleLast = [until julianNumber];
+ }
+ else {
+ jnRuleLast = (interval * [self->rrule repeatCount] * 7)
+ + jnFirst;
+ if (jnRuleLast < jnStart)
+ return nil;
+ }
+ /* jnStart < jnRuleLast < jnEnd ? */
+ if (jnEnd > jnRuleLast)
+ jnEnd = jnRuleLast;
+ }
+
+ startEndCount = (jnEnd - jnStart) + 1;
+ ranges = [NSMutableArray arrayWithCapacity:startEndCount];
+ byDayMask = [self->rrule byDayMask];
+ if (!byDayMask) {
+ for (i = 0 ; i < startEndCount; i++) {
+ long jnCurrent;
+
+ jnCurrent = jnStart + i;
+ if (jnCurrent >= jnFirst) {
+ long jnDiff;
+
+ jnDiff = jnCurrent - jnFirst; /* difference in days */
+ if ((jnDiff % (interval * 7)) == 0) {
+ NSCalendarDate *start, *end;
+ NGCalendarDateRange *r;
+
+ start = [NSCalendarDate dateForJulianNumber:jnCurrent];
+ start = [start hour: [firStart hourOfDay]
+ minute:[firStart minuteOfHour]
+ second:[firStart secondOfMinute]];
+ end = [start addTimeInterval:[self->firstRange duration]];
+ r = [NGCalendarDateRange calendarDateRangeWithStartDate:start
+ endDate:end];
+ [ranges addObject:r];
+ }
+ }
+ }
+ }
+ else {
+ [self errorWithFormat:@"Cannot calculate rules with byDayMask, yet!"];
+ }
+ return ranges;
+}
+
+- (NSCalendarDate *)lastInstanceStartDate {
+ if ([self->rrule repeatCount] > 0) {
+ long jnFirst, jnRuleLast;
+ NSCalendarDate *firStart, *until;
+
+ firStart = [self->firstRange startDate];
+ jnFirst = [firStart julianNumber];
+ jnRuleLast = ([self->rrule repeatInterval] *
+ [self->rrule repeatCount] * 7) +
+ jnFirst;
+ until = [NSCalendarDate dateForJulianNumber:jnRuleLast];
+ until = [until hour: [firStart hourOfDay]
+ minute:[firStart minuteOfHour]
+ second:[firStart secondOfMinute]];
+ return until;
+ }
+ return [super lastInstanceStartDate];
}
@end /* iCalWeeklyRecurrenceCalculator */