为重复日期创建新的数组条目

时间:2014-02-01 16:50:17

标签: ios iphone objective-c parsing nsarray

我正在解析.ics文件,我得到了一个名为rrule的属性。我成功解析并添加到数组中的对象是具有多个属性的对象。

rrule属性(对象的属性之一)是NSString并提供以下信息:Rrule:FREQ=WEEKLY;UNTIL=20140322;INTERVAL=1;BYDAY=FR

现在我想在数组中添加另一个对象,每个新条目都有相同的信息,直到达到“UNTIL DATE”,只有startDate和endDate才会改变。在上面的例子中,28日开始时,将添加7.3和14.3和21.3的对象。 22.3是星期六,在这一天之后,没有其他星期五应该添加。小时,分钟和秒也应保持不变。

任何可以帮助我的人?我设法解析.ics文件中的信息,但我很难实现这个,所以我真的可以使用我解析的信息。

数组中对象的其他属性称为:

NSString *summary, NSString *location, NSDate *startDate, NSDate *endDate, NSString *rrule, NSString *category, BOOL isExam

编辑: 好的,这是我根据你的答案(sbooth)尝试的:

NSDictionary *stringToNumber = [NSDictionary dictionaryWithObjectsAndKeys:
                                [NSNumber numberWithInt:2],@"MO",
                                [NSNumber numberWithInt:3],@"TU",
                                [NSNumber numberWithInt:4],@"WE",
                                [NSNumber numberWithInt:5],@"TH",
                                [NSNumber numberWithInt:6],@"FR",
                                [NSNumber numberWithInt:7],@"SA",
                                [NSNumber numberWithInt:1],@"SU",
                                nil];

for(DECalEntry *entry in planEntries) {
    if(entry.rrule.length > 1) { //rrule is not empty
        NSDateComponents *week = [[NSDateComponents alloc]init];
        [week setWeek:1];

        NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
        NSDateComponents *comp = [[NSDateComponents alloc] init];
        NSNumber *number = [stringToNumber objectForKey:[self stringBetweenString:@"BYDAY=" andString:@"" andString:entry.rrule]];

        [comp setWeekday:[number intValue]];

        NSDate *newStartDate = [gregorian dateByAddingComponents:comp toDate:entry.startDate options:0];
        NSDate *newEndDate = [gregorian dateByAddingComponents:comp toDate:entry.endDate options:0];

        NSDateFormatter *df = [[NSDateFormatter alloc] init];
        [df setDateFormat:@"yyyyMMdd"];
        NSDate *untilDate = [df dateFromString: [self stringBetweenString:@"UNTIL=" andString:@";" andString:entry.rrule]];
        while([newStartDate compare:untilDate] == NSOrderedAscending) {
            DECalEntry *newEntry = [[DECalEntry alloc]init];
            newEntry.summary = entry.summary;
            newEntry.location = entry.location;
            newEntry.isExam = entry.isExam;
            newEntry.rrule = @"";
            newEntry.startDate = newStartDate;
            newEntry.endDate = newEndDate;
            newEntry.category = entry.category;

            [self.helpArray addObject:newEntry];

            newStartDate =[gregorian dateByAddingComponents:comp toDate:newStartDate options:0];
            newEndDate =[gregorian dateByAddingComponents:comp toDate:newEndDate options:0];

        }
    }

    if([self.helpArray count] > 0) {
        for(DECalEntry *entries in self.helpArray) {
            [planEntries addObject:entries];
        }
    }

和stringBetweenSting方法:

-(NSString*)stringBetweenString:(NSString*)start andString:(NSString*)end  andString:(NSString *)string{
    NSScanner* scanner = [NSScanner scannerWithString:string];
    [scanner setCharactersToBeSkipped:nil];
    [scanner scanUpToString:start intoString:NULL];
    if ([scanner scanString:start intoString:NULL]) {
        NSString* result = nil;
        if ([scanner scanUpToString:end intoString:&result]) {
            return result;
        }
    }
    return nil;
}

EDIT2:好的,我终于开始工作了。问题是,每天有一条规则,而不是每周一次。这导致while循环永不终止。现在一切正常,再次感谢!

1 个答案:

答案 0 :(得分:0)

您可以使用NSDateComponentsNSDate执行此操作。第一步是将规则解析为适当的NSDateComponents以添加到开始日期。我不知道您正在使用的规则的完整语法,但是对于您给出的组件的示例将包含一周,因为频率是每周一次:

NSDateComponents *week = [[NSDateComponents alloc] init];
[dc setWeek:1];

由于您已经知道间隔何时开始,因此计算的开始日期应该是startDate之后的第一个星期五。使用公历来查找任意日期之后的第一个星期五:

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *fri = [[NSDateComponents alloc] init];
[fri setWeekday:6];

NSDate *firstFridayFollowing = [gregorian dateByAddingDateComponents:fri toDate:startDate options:0];

一旦你知道周五的第一个星期五就可以增加几周:

NSDate *oneWeekLater = [gregorian dateByAddingDateComponents:week toDate:firstFridayFollowing options:0];

这样做很简单,直到下一个生成日期晚于结束日期。