这是一个益智游戏。我使用以下方法来计算今天的日期和即将到来的生日之间的天数:
-(int) daysTillBirthday: (NSDate*)aDate {
// check to see if valid date was passed in
//NSLog(@"aDate passed in is %@",aDate);
if (aDate == nil) {
//NSLog(@"aDate is NULL");
return -1; // return a negative so won't be picked in table
}
//** HOW MANY DAYS TO BDAY
NSDate *birthDay = aDate; // [calendar dateFromComponents:myBirthDay];
//NSLog(@"birthDay: %@, today: %@",birthDay, [NSDate date]);
NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDateComponents *thisYearComponents = [calendar components:NSYearCalendarUnit fromDate:[NSDate date]];
NSDateComponents *birthDayComponents = [calendar components:NSMonthCalendarUnit|NSDayCalendarUnit fromDate:birthDay];
[birthDayComponents setYear:[thisYearComponents year]];
NSDate *birthDayThisYear = [calendar dateFromComponents:birthDayComponents];
//NSLog(@"birthDayThisYear: %@",birthDayThisYear);
NSDateComponents *differenceHours = [calendar components:NSHourCalendarUnit fromDate:[NSDate date] toDate:birthDayThisYear options:0];
NSDateComponents *differenceDays = [calendar components:NSDayCalendarUnit fromDate:[NSDate date] toDate:birthDayThisYear options:0];
// NSLog(@"difference days: %i, hours %i",[differenceDays day],[differenceHours hour]);
//*** I added this to try and correct the "error" ***
if ([differenceDays day] == 0) { // is it today, or tomorrow?
if (([differenceHours hour] <= 0) && ([differenceHours hour] >= -24)) { // must be today
//NSLog(@"TODAY");
return (0);
[calendar release];
}else if (([differenceHours hour] >= 0) && ([differenceHours hour] <= 24)) {
//NSLog(@"TOMORROW");
return (1);
[calendar release];
}
}
if ([differenceDays day] < 0) {
// this years birthday is already over. calculate distance to next years birthday
[birthDayComponents setYear:[thisYearComponents year]+1];
birthDayThisYear = [calendar dateFromComponents:birthDayComponents];
differenceDays = [calendar components:NSDayCalendarUnit fromDate:[NSDate date] toDate:birthDayThisYear options:0];
}
return ([differenceDays day]);
[calendar release];
}
一切正常,但结果不准确!我经常发现生日与今天很接近,但相差一天,导致 [differenceDays day] 相同!即,如果今天是 2011 年 6 月 6 日,并且我有两个生日,一个是 6/7/2011,另一个是 6/8/2011,那么它们都显示为 1 天后!
谁有更好的方法来准确计算这个,或者可以找出问题所在?
非常感谢。
最佳答案
NSCalendar
提供了一种更简单的方法来执行此操作:
NSDate *birthday = ...; // the birthday
NSDate *today = [NSDate date];
NSCalendar *c = [NSCalendar currentCalendar];
NSInteger birthdayDayOfYear = [c ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:birthday];
NSInteger todayDayOfYear = [c ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:today];
NSInteger different = birthdayDayOfYear - todayDayOfYear;
基本上,我们计算出今天距离今年有多远(即今天 [6 月 5 日] 是一年中的第 156 天),然后将它们相减以计算出今年有多少天他们之间。
当然,此方法依赖于目标日期与当前日期在同一年的假设。不过,我认为解决这个问题相当容易。
<小时/>另一种更简单的方法可以解决多年差异,如下所示:
NSDateComponents *d = [[NSCalendar currentCalendar] components:NSDayCalendarUnit fromDate:today toDate:birthday options:0];
NSInteger difference = [d day];
<小时/>
如果您需要确保生日是在未来,这也很容易完成:
NSDateComponents *year = [[[NSDateComponents alloc] init] autorelease];
NSInteger yearDiff = 1;
NSDate *newBirthday = birthday;
while([newBirthday earlierDate:today] == newBirthday) {
[year setYear:yearDiff++];
newBirthday = [[NSCalendar currentCalendar] dateByAddingComponents:year toDate:birthday options:0];
}
//continue on with the 2-line calculation above, using "newBirthday" instead.
更新我更新了上面的循环,始终从原始日期一次递增n年,而不是逐年递增。如果某人出生于 2 月 29 日,则增加一年将得到 3 月 1 日,一旦再次进入闰年,这将是错误的。通过每次从原始日期跳转,我们就不会遇到这个问题。
关于iPhone:计算距下一个生日天数的方法不准确--?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6246727/