生成连续的 NSDates 序列
Generate consecutive sequence of NSDates
给定一些开始日期,我想在此开始日期后连续 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];
}
问题: startDate 的重新分配是否正常,因为我正在向 self.days 添加相同的对象?
没关系,因为您实际上并没有添加同一个对象。 dateByAddingComponents: returns 一个新对象,因此当您将其分配给 startDate 时,您会将对旧对象的引用替换为对新对象的引用
创建日期序列并不像听起来那么简单。实际上它包含在伟大的 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];
}
所以,是的,重新分配在技术上是可以的,但在这种特殊情况下,它可能会导致意想不到的麻烦。
给定一些开始日期,我想在此开始日期后连续 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];
}
问题: startDate 的重新分配是否正常,因为我正在向 self.days 添加相同的对象?
没关系,因为您实际上并没有添加同一个对象。 dateByAddingComponents: returns 一个新对象,因此当您将其分配给 startDate 时,您会将对旧对象的引用替换为对新对象的引用
创建日期序列并不像听起来那么简单。实际上它包含在伟大的 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];
}
所以,是的,重新分配在技术上是可以的,但在这种特殊情况下,它可能会导致意想不到的麻烦。