Created
November 23, 2010 18:19
-
-
Save mnbi/712238 to your computer and use it in GitHub Desktop.
convert a RFC3339 date string into a NSDate object
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
// convert a RFC3399 date (& time) into a NSDate object | |
// NOTE: This function ignores fractions of a second in the RFC3339 | |
// representation. | |
NSDate *getDateObject(NSString *rfc3339) | |
{ | |
// Date and Time representation in RFC3399: | |
// Pattern #1: "YYYY-MM-DDTHH:MM:SSZ" | |
// 1 | |
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 | |
// [Y|Y|Y|Y|-|M|M|-|D|D|T|H|H|:|M|M|:|S|S|Z] | |
// | |
// Pattern #2: "YYYY-MM-DDTHH:MM:SS.sssZ" | |
// 1 2 | |
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 | |
// [Y|Y|Y|Y|-|M|M|-|D|D|T|H|H|:|M|M|:|S|S|.|s|s|s|Z] | |
// NOTE: The number of digits in the "sss" part is not defined. | |
// | |
// Pattern #3: "YYYY-MM-DDTHH:MM:SS+HH:MM" | |
// 1 2 | |
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 | |
// [Y|Y|Y|Y|-|M|M|-|D|D|T|H|H|:|M|M|:|S|S|+|H|H|:|M|M] | |
// | |
// Pattern #4: "YYYY-MM-DDTHH:MM:SS.sss+HH:MM" | |
// 1 2 | |
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 | |
// [Y|Y|Y|Y|-|M|M|-|D|D|T|H|H|:|M|M|:|S|S|.|s|s|s|+|H|H|:|M|M] | |
// NOTE: The number of digits in the "sss" part is not defined. | |
// NSDate format: "YYYY-MM-DD HH:MM:SS +HHMM". | |
NSCharacterSet *setOfT = [NSCharacterSet characterSetWithCharactersInString:@"tT"]; | |
NSRange tMarkPos = [rfc3339 rangeOfCharacterFromSet:setOfT]; | |
if (tMarkPos.location == NSNotFound) return nil; | |
// extract date and time part: | |
NSString *datePart = [rfc3339 substringToIndex:tMarkPos.location]; | |
NSString *timePart = [rfc3339 substringWithRange:NSMakeRange(tMarkPos.location + tMarkPos.length, 8)]; | |
NSString *restPart = [rfc3339 substringFromIndex:tMarkPos.location + tMarkPos.length + 8]; | |
// extract time offset part: | |
NSString *tzSignPart, *tzHourPart, *tzMinPart; | |
NSCharacterSet *setOfZ = [NSCharacterSet characterSetWithCharactersInString:@"zZ"]; | |
NSRange tzPos = [restPart rangeOfCharacterFromSet:setOfZ]; | |
if (tzPos.location == NSNotFound) { // Pattern #3 or #4 | |
NSCharacterSet *setOfSign = [NSCharacterSet characterSetWithCharactersInString:@"+-"]; | |
NSRange tzSignPos = [restPart rangeOfCharacterFromSet:setOfSign]; | |
if (tzSignPos.location == NSNotFound) return nil; | |
tzSignPart = [restPart substringWithRange:tzSignPos]; | |
tzHourPart = [restPart substringWithRange:NSMakeRange(tzSignPos.location + tzSignPos.length, 2)]; | |
tzMinPart = [restPart substringFromIndex:tzSignPos.location + tzSignPos.length + 2 + 1]; | |
} else { // Pattern #1 or #2 | |
// "Z" means UTC. | |
tzSignPart = @"+"; | |
tzHourPart = @"00"; | |
tzMinPart = @"00"; | |
} | |
// construct a date string in the NSDate format | |
NSString *dateStr = [NSString stringWithFormat:@"%@ %@ %@%@%@", datePart, timePart, tzSignPart, tzHourPart, tzMinPart]; | |
NSDate *dateObj = [[NSDate alloc] initWithString:dateStr]; | |
[dateObj autorelease]; | |
return dateObj; | |
} | |
void testGetDateObject(NSString *rfc3339) | |
{ | |
NSLog(@"----------------------------------------"); | |
NSLog(@"RFC3339 Format: %@", rfc3339); | |
NSDate *date = getDateObject(rfc3339); | |
NSLog(@"NSDate object: %@", date); | |
NSString *dateFormat = @"%Y-%m-%d %H:%M:%S %z"; | |
NSString *dateInDefaultTZ = [date descriptionWithCalendarFormat:dateFormat timeZone:nil locale:nil]; | |
NSLog(@"Default TZ: %@", dateInDefaultTZ); | |
NSTimeZone *aTimeZone = [NSTimeZone timeZoneWithName:@"UTC"]; | |
NSString *dateInUTC = [date descriptionWithCalendarFormat:dateFormat timeZone:aTimeZone locale:nil]; | |
NSLog(@"UTC: %@", dateInUTC); | |
} | |
int main (int argc, const char * argv[]) { | |
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; | |
// insert code here... | |
testGetDateObject(@"2010-11-22T12:34:56Z"); | |
testGetDateObject(@"2010-11-22t12:34:56z"); | |
testGetDateObject(@"2010-11-22T12:34:56.123Z"); | |
testGetDateObject(@"2010-11-22t12:34:56.123z"); | |
testGetDateObject(@"2010-11-22T12:34:56+09:00"); | |
testGetDateObject(@"2010-11-22t12:34:56+09:00"); | |
testGetDateObject(@"2010-11-22T12:34:56.123+09:00"); | |
testGetDateObject(@"2010-11-22t12.34.56.123+09:00"); | |
testGetDateObject(@"2010-11-22T12:34:56-05:00"); | |
testGetDateObject(@"2010-11-22T12:34:56.123-05:00"); | |
[pool drain]; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment