生成连续的NSDates序列

时间:2015-01-01 21:25:23

标签: objective-c nsdate

鉴于一些startDate,我想在startDate之后连续几天退化x个数。我试图使用以下代码:

// Generate dates
self.days = [[NSMutableArray alloc] init];
NSDate *startDate = [NSDate date];

NSCalendar *theCalendar = [NSCalendar currentCalendar];
NSDateComponents *dayComponent = [[NSDateComponents alloc] init];
dayComponent.day = 1;

for (int i = 1; i < self.mygoal.goalDays; i++) {
    [self.days addObject:startDate];
    startDate = [theCalendar dateByAddingComponents:dayComponent toDate:startDate options:0];
}

问题:如果我将同一个对象添加到self.days,那么startDate的重新分配是否正常?

2 个答案:

答案 0 :(得分:3)

创建一系列日期并不像听起来那么简单。实际上它包含在伟大的WWDC2011 video«执行日历计算»中。

您每天都会在每个循环中添加到最后一个日期。但实际上,如果时间是在切换当天的时间内以及随后的任何日期,由于日期将为零,这将在DST的时区中失败。

如果您改变循环中的日期组件并将其添加到原始satrtdate,它将仅影响DST切换的那一天。

还可以处理您可以将开始日期的小时设置为安全的 - 正如中午 - 因为所有开关都在夜间执行。

考虑到所有这些,我会使用类似的东西创建一系列日期,时间设置为一天的开始:

NSUInteger numberOfDays = 10;
NSCalendar *cal = [NSCalendar currentCalendar];
NSDate *startDate = [cal dateFromComponents:({
    NSDateComponents *comps = [[NSDateComponents alloc] init];
    comps.year = 2015;
    comps.month = 1;
    comps.day = 2;
    comps.hour = 12; // for DST-safety
    comps;
})];


NSMutableArray *dates = [@[] mutableCopy];

for (NSUInteger i =0 ; i < numberOfDays; ++i) {
    NSDateComponents *comps = [[NSDateComponents alloc] init];
    comps.day = i;
    NSDate *date = [cal dateByAddingComponents:comps
                                        toDate:startDate
                                       options:0];

    // set date to beginning of day
    [cal rangeOfUnit:NSCalendarUnitDay
           startDate:&date
            interval:NULL
             forDate:date];

    [dates addObject:date];
}

所以,是的,重新分配在技术上是可以的,但在这种特殊情况下,它可能会导致意外的麻烦。

答案 1 :(得分:0)

没关系,因为你实际上没有添加同一个对象。 dateByAddingComponents:会返回一个新对象,因此当您将其分配给startDate时,您将对旧对象的引用替换为对新对象的引用