I\'m trying to use an NSDateFormatter to parse dates that are in either of these formats
@\"2013-02-01T14:21:00\"
or
@\"201
The correct approach since iOS 10 is to use ISO8601DateFormatter
specifically created to handle all variations of ISO 8601 date strings. Please see the example below:
let date = Date()
var string: String
let formatter = ISO8601DateFormatter()
string = formatter.string(from: date)
let GMT = TimeZone(abbreviation: "GMT")
let options: ISO8601DateFormatOptions = [.withInternetDateTime, .withDashSeparatorInDate, .withColonSeparatorInTime, .withTimeZone]
string = ISO8601DateFormatter.string(from: date, timeZone: GMT, formatOptions: options)
And Objective-C version:
NSDate *date = [NSDate date];
NSString *string;
NSISO8601DateFormatter *formatter = [[NSISO8601DateFormatter alloc] init];
string = [formatter stringFromDate:date];
NSTimeZone *GMT = [NSTimeZone timeZoneWithAbbreviation: @"GMT"];
NSISO8601DateFormatOptions options = NSISO8601DateFormatWithInternetDateTime | NSISO8601DateFormatWithDashSeparatorInDate | NSISO8601DateFormatWithColonSeparatorInTime | NSISO8601DateFormatWithTimeZone;
string = [NSISO8601DateFormatter stringFromDate:date timeZone:GMT formatOptions:options];
As far as I know there is no way to make optional parameters.
The usual solution is to use two formatters, one for each format. To decide which formatter to use, you can either
Count the number of characters in the date string (as suggested in Parsing a RFC 822 date with NSDateFormatter)
Just try both formatters and get the first non-nil
result.
Since your date formats are similar, you can go with only one formatter and if the date string is too short, append .000
before using the formatter.
I wrote an universal parser which dropped milliseconds part.
@implementation JSONModel(NSPAdditions)
- (NSDate *)NSDateFromNSString:(NSString*)string {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
NSArray* parts = [string componentsSeparatedByCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@" T"]];
if ([parts count] <= 1) {
return [formatter dateFromString:string];
}
NSString *part0 = parts[0];
NSAssert([part0 length] == [@"yyyy-MM-dd" length], @"Date format error");
NSString *part1 = parts[1];
if ([part1 length] > [@"HH:mm:ss" length]) {
part1 = [part1 substringToIndex:[@"HH:mm:ss" length]];
}
NSString *fmted = [NSString stringWithFormat:@"%@ %@", part0, part1];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
return [formatter dateFromString:fmted];
}
@end