When transferring dates by wire from the client to the server and vice versa, I will format the date on a string for JSON using the format @"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" with the locale @"en_US_POSIX" . The same formatter provides an instance of NSDate from the date strings returned from the server to the client.
To check conversions, I'm trying to use NSDateComponents and NSCalendar to create an independent date, used to check the date from formatting. However, NSDate instances created from NSCalendar and NSDateComponents are slightly different from the NSDate instances provided by NSDateFormatter . I do not understand why. Different dates produce a different amount of difference. We apologize for yet another NSDate / NSDateFormatter , but hope you find it somewhat new.
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)]; } }
source share