Thank You Ole. I finally got my head around that NSDate
and NSDateformatter
are just abstract
concepts and that a "date" is truly saved as "milliseconds or seconds since 1/1 2001" internally.
I did a "Proof of concept" to really understand it. Now it is suddenly very simple to write some categories on NSDate
that makes sure that dates going in and coming out are correctly formatted, but all calculations are done on the raw UTC date.
- (void) testGMTDateParser {
NSMutableArray *arrayDates = [NSMutableArray arrayWithCapacity:5];
[self setParsedDates:arrayDates];
NSMutableArray *arrayGMTOffsets = [NSMutableArray arrayWithCapacity:5];
[self setParsedGMTOffsets:arrayGMTOffsets];
NSString *date00 = @"2010-03-30T12:00:00";
NSString *GMT00 = @"-2";
NSString *date01 = @"2010-03-30T12:00:00";
NSString *GMT01 = @"-1";
NSString *date02 = @"2010-03-30T12:00:00";
NSString *GMT02 = @"+0";
NSString *date03 = @"2010-03-30T12:00:00";
NSString *GMT03 = @"+1";
NSString *date04 = @"2010-03-30T12:00:00";
NSString *GMT04 = @"+2";
NSArray *dateArray = [NSArray arrayWithObjects:date00, date01, date02, date03, date04,nil];
NSArray *GMTArray = [NSArray arrayWithObjects:GMT00, GMT01, GMT02, GMT03, GMT04, nil];
for (int i = 0; i < [dateArray count]; i++) {
[self parseDateString:[dateArray objectAtIndex:i] withGMTString:[GMTArray objectAtIndex:i]];
}
}
Parse the Dates with regards to their respective GMT offset. This will make sure the UTC time saved
internally is correct.
-(void) parseDateString:(NSString*) dateString withGMTString:(NSString*) GMTString {
NSInteger hoursFromGMT = [GMTString intValue];
NSInteger secondsFromGMT = (hoursFromGMT * 60 * 60);
NSTimeZone *timeZone = [NSTimeZone timeZoneForSecondsFromGMT:secondsFromGMT];
NSDateFormatter *dateFormatterGMTAware = [[NSDateFormatter alloc] init];
[dateFormatterGMTAware setTimeZone:timeZone];
[dateFormatterGMTAware setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"];
NSDate *date = [dateFormatterGMTAware dateFromString:dateString];
[dateFormatterGMTAware release];
[self.parsedDates addObject:date];
[self.parsedGMTOffsets addObject:[NSNumber numberWithInt:secondsFromGMT]];
}
Set up the NSDateformatter to print out the saved dates with regards to GMT offset.
all dates can now be manipulated as UTC with no regards to GMT.
-(void) printOutDates {
for (int i = 0; i < [self.parsedDates count]; i++) {
NSTimeZone *timeZone = [NSTimeZone timeZoneForSecondsFromGMT:[[parsedGMTOffsets objectAtIndex:i] intValue]];
NSDateFormatter *dateFormatterGMTAware = [[NSDateFormatter alloc] init];
[dateFormatterGMTAware setTimeZone:timeZone];
[dateFormatterGMTAware setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
NSLog(@"%@ in Original GMT", [dateFormatterGMTAware stringFromDate:[parsedDates objectAtIndex:i]]);
NSLog(@"%@ in Local GMT\n\n", [parsedDates objectAtIndex:i]);
}
}
2010-03-30 18:50:31.284 TimeZonePOC[39830:207] 2010-03-30 12:00:00 -0200 in Original GMT
2010-03-30 18:50:31.285 TimeZonePOC[39830:207] 2010-03-30 16:00:00 +0200 in Local GMT
2010-03-30 18:50:31.287 TimeZonePOC[39830:207] 2010-03-30 12:00:00 -0100 in Original GMT
2010-03-30 18:50:31.287 TimeZonePOC[39830:207] 2010-03-30 15:00:00 +0200 in Local GMT
2010-03-30 18:50:31.289 TimeZonePOC[39830:207] 2010-03-30 12:00:00 +0000 in Original GMT
2010-03-30 18:50:31.289 TimeZonePOC[39830:207] 2010-03-30 14:00:00 +0200 in Local GMT
2010-03-30 18:50:31.290 TimeZonePOC[39830:207] 2010-03-30 12:00:00 +0100 in Original GMT
2010-03-30 18:50:31.292 TimeZonePOC[39830:207] 2010-03-30 13:00:00 +0200 in Local GMT
2010-03-30 18:50:31.292 TimeZonePOC[39830:207] 2010-03-30 12:00:00 +0200 in Original GMT
2010-03-30 18:50:31.294 TimeZonePOC[39830:207] 2010-03-30 12:00:00 +0200 in Local GMT