为什么来自NSCalendar和NSDateFormatter的NSDate实例的值略有不同?

时间:2013-05-28 16:25:06

标签: objective-c nsdate nsdateformatter

当通过网络将日期从客户端传递到服务器并再次返回时,我使用@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"语言环境的@"en_US_POSIX"格式将日期格式化为JSON的字符串。相同的格式化程序从服务器返回到客户端的日期字符串中提供NSDate的实例。

要测试转化,我尝试使用NSDateComponentsNSCalendar生成一个独立日期,用于验证格式化程序的日期。但是,NSDateNSCalendar创建的NSDateComponents实例与NSDate提供的NSDateFormatter实例的差异略有不同。我不懂为什么。不同的日期产生不同数量的差异。我为另一个NSDate / NSDateFormatter问题道歉,但希望您觉得它有点新颖。

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
dateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
dateFormatter.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSMutableArray *valuesWithError = [NSMutableArray arrayWithCapacity:750];
NSMutableArray *valuesThatMatch = [NSMutableArray arrayWithCapacity:250];

for (NSInteger milliseconds = 0; milliseconds < 1000; milliseconds++) {
    NSString *dateString = [NSString stringWithFormat:@"2001-01-01T00:00:00.%03dZ", milliseconds];
    NSLog(@"%@", dateString);

    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    calendar.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
    calendar.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];

    NSDateComponents *dc = [[NSDateComponents alloc] init];
    dc.year = 2001;
    dc.month = 1;
    dc.day = 1;
    dc.hour = 0;
    dc.minute = 0;
    dc.second = 0;

    NSDate *expectedDate = [calendar dateFromComponents:dc];

    NSTimeInterval baseInterval = [expectedDate timeIntervalSinceReferenceDate];
    double mulitplier = 0.001;
    NSTimeInterval millisecondsToAdd = milliseconds * mulitplier;
    baseInterval += millisecondsToAdd;

    expectedDate = [NSDate dateWithTimeIntervalSinceReferenceDate:baseInterval];

    NSDate *dateFromFormat = [dateFormatter dateFromString:dateString];

    NSTimeInterval expectedDateFromReferenceDate = [expectedDate timeIntervalSinceReferenceDate];
    NSTimeInterval dateFromFormatFromReferenceDate = [dateFromFormat timeIntervalSinceReferenceDate];

    NSTimeInterval differenceByTimeIntervalSubtraction = ABS(expectedDateFromReferenceDate - dateFromFormatFromReferenceDate);

    NSTimeInterval differenceByTimeIntervalFromDate = [expectedDate timeIntervalSinceDate:dateFromFormat];

    if (![expectedDate isEqualToDate:dateFromFormat]) {
        NSLog(@"Difference = %e", differenceByTimeIntervalSubtraction);
        [valuesWithError addObject:@(milliseconds)];
    } else {
        [valuesThatMatch addObject:@(milliseconds)];
    }
}

0 个答案:

没有答案