How to parse ISO 8601 using NSDateFormatter with optional milliseconds part

后端 未结 3 1921
耶瑟儿~
耶瑟儿~ 2020-12-03 11:09

I\'m trying to use an NSDateFormatter to parse dates that are in either of these formats

@\"2013-02-01T14:21:00\"

or

@\"201         


        
相关标签:
3条回答
  • 2020-12-03 11:26

    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];
    
    0 讨论(0)
  • 2020-12-03 11:32

    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

    1. Count the number of characters in the date string (as suggested in Parsing a RFC 822 date with NSDateFormatter)

    2. 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.

    0 讨论(0)
  • 2020-12-03 11:34

    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
    
    0 讨论(0)
提交回复
热议问题