为什么NSDate会跨设备不一致?

时间:2011-04-18 00:30:50

标签: iphone objective-c ios nsdate nscalendar

在给定希伯来年份的情况下,以下方法会尝试计算NSHebrew日历对象一年中的天数。出于某种原因,我在各种设备上获得了不一致的结果。测试用例是1996年5月25日。一台设备比另一台设备返回一天(正确的值),这是一天的设备。

- (NSInteger) lengthOfYearForYear:(NSInteger)year{

//
//  Then get the first day of the current hebrew year
//

NSCalendar *hebrewCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSHebrewCalendar];

NSDateComponents *roshHashanaComponents = [[[NSDateComponents alloc] init ]autorelease];

[roshHashanaComponents setDay:1];
[roshHashanaComponents setMonth:1];
[roshHashanaComponents setYear:year];
[roshHashanaComponents setHour:12];
[roshHashanaComponents setMinute:0];
[roshHashanaComponents setSecond:0];

NSDate *roshHashanaDate = [hebrewCalendar dateFromComponents:roshHashanaComponents];

//
//  Then convert that to gregorian
//

NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *gregorianDayComponentsForRoshHashana = [gregorianCalendar components:NSWeekdayCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:roshHashanaDate];

//Determine the day of the week of the first day of the current hebrew year

NSDate *oneTishreiAsGregorian = [gregorianCalendar dateFromComponents:gregorianDayComponentsForRoshHashana];

//
//  Then get the first day of the next hebrew year
//

NSDateComponents *roshHashanaOfNextYearComponents = [[NSDateComponents alloc] init ];

NSInteger tempYear = year+1;

[roshHashanaOfNextYearComponents setDay:1];
[roshHashanaOfNextYearComponents setMonth:1];
[roshHashanaOfNextYearComponents setYear:tempYear];
[roshHashanaOfNextYearComponents setHour:12];
[roshHashanaOfNextYearComponents setMinute:0];
[roshHashanaOfNextYearComponents setSecond:0];

NSDate *roshHashanaOfNextYearAsDate = [hebrewCalendar dateFromComponents:roshHashanaOfNextYearComponents];

[roshHashanaOfNextYearComponents release];

[hebrewCalendar release];

//
//  Then convert that to gregorian
//

NSDateComponents *gregorianDayComponentsForRoshHashanaOfNextYear = [gregorianCalendar components:NSWeekdayCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:roshHashanaOfNextYearAsDate];

//Determine the first day of the week of the next hebrew year
NSDate *oneTishreiOfNextYearAsGregorian = [gregorianCalendar dateFromComponents:gregorianDayComponentsForRoshHashanaOfNextYear];

//  Length of this year in days 
NSTimeInterval totalDaysInTheYear = [oneTishreiOfNextYearAsGregorian timeIntervalSinceReferenceDate] - [oneTishreiAsGregorian timeIntervalSinceReferenceDate];

//
//   We round here because of slight offsets in the Gregorian calendar.
//

totalDaysInTheYear = round(totalDaysInTheYear/86400);

if(totalDaysInTheYear == 353 || totalDaysInTheYear == 383){
    totalDaysInTheYear = 0;
}else if(totalDaysInTheYear == 354 || totalDaysInTheYear == 384){
    totalDaysInTheYear = 1;
}else if(totalDaysInTheYear == 355 || totalDaysInTheYear == 385){
    totalDaysInTheYear = 2;
}

return totalDaysInTheYear;

}

认为可能是因为我没有使用NSHourCalendarUnit更小,但我不确定。那会这样吗?还有什么是明显不正确的吗?

2 个答案:

答案 0 :(得分:0)

我的beta测试人员之间的设备之间有相同的观察结果。不同的蜂窝网络意味着不同的时间信愚蠢,但他们利用他们的时间进行计费,因此他们在蜂窝网络中提供自己的信号。

iPod由主机设置,主机通常由NTP服务器设置。那些应该非常同步。

答案 1 :(得分:0)

此代码的问题在于我遗漏了NSDateComponents的标识符。 NSDateComponents没有必需的标识符,会扰乱小时,分钟和秒,从而在不同设备上产生不同的年份长度。