无法使用dateFromString转换原始日期

时间:2012-12-21 22:06:57

标签: objective-c date nsstring converter nsdateformatter

我正在尝试使用以下代码转换时间字符串

NSString *origDate = @"2012-12-06T09:27:18+08:00";
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setFormatterBehavior:NSDateFormatterBehavior10_4];
[df setDateFormat:@"yyyy-mm-dd HH:mm:ss VVVV"];
NSDate *convertedDate = [df dateFromString:origDate]; 

然而,当我打印convertedDate时,它返回null。我的猜测是你使用的日期格式不匹配。如何修改代码才能使其正常工作?我可以使用什么格式来匹配我的字符串?

编辑(参考苹果的文档后)

我检查了苹果页面上的日期格式文档,并找到了以下代码

NSDateFormatter *rfc3339DateFormatter = [[NSDateFormatter alloc] init];
NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];

[rfc3339DateFormatter setLocale:enUSPOSIXLocale];
[rfc3339DateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
[rfc3339DateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

// Convert the RFC 3339 date time string to an NSDate.
NSDate *date = [rfc3339DateFormatter dateFromString:rfc3339DateTimeString];

上述格式似乎与原始日期字符串“2012-12-06T09:27:18 + 08:00”中的格式相符。但是我仍然得到一个空值。我越来越近了吗?我怎么能更新这个?

2 个答案:

答案 0 :(得分:0)

根据您的原始输入,提供给日期格式化程序的格式字符串应该完成工作:

@"yyyy'-'MM'-'dd'T'HH':'mm':'ssZZZZZ"

注意:我在Mac OS X 10.8.2下进行了测试。

答案 1 :(得分:0)

格式String将在iOS6上解析(不是iOS5 - > nil),但它对输出无用,因为解析的日期会丢失它的时区信息。 iOS6中的输出类似于“2012-12-06T17:27:18Z”,这可能取决于时区是否设置为GMT。

我的代码:

    static NSDateFormatter    *gXmlDateFormatter = nil;
// lazy init
+ (NSDateFormatter *)xmlDateFormatter
{
    // e.g. updateDateTime="2012-09-18T11:06:19+00:00"
    if (gXmlDateFormatter == nil) {
        // prepare for parsinf Arinc-ISO-XML-dates input
        gXmlDateFormatter = [[NSDateFormatter alloc] init];
        gXmlDateFormatter = [NSTimeZone timeZoneForSecondsFromGMT:0];
        gXmlDateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];

        gXmlDateFormatter.dateFormat = @"yyyy'-'MM'-'dd'T'HH':'mm':'ssZZZZZ";    // only parsing! in iOS 6 (iOS5 will parse nil)
//        gXmlDateFormatter.dateFormat = @"yyyy'-'MM'-'dd'T'HH':'mm':'ssZ";        // all iOS but with NO colons in timeZone (add/remove)
    }
    NSLog(@"gXmlDateFormatter:%@",gXmlDateFormatter);
    return gXmlDateFormatter;
}
// there's a problem with the above dateformater and iOS5 creating nil-results
+ (NSDate *)dateFromXMLString:(NSString *)arincDateString
{
    NSString *dateString = arincDateString;

    // xmlDateStrings may contain a ':' in the timezone part. iOS and Unicode DO NOT
    // so always remove the xml-standard colon ':' from the timezone to make it iOS/Unicode compatible
    // xml: http://www.w3schools.com/schema/schema_dtypes_date.asp
    // iOS: http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns)
    NSRange zRange = NSMakeRange(arincDateString.length-3, 1);
    dateString = [arincDateString stringByReplacingOccurrencesOfString:@":" withString:@"" options:0 range:zRange];

    NSDate *date = [self.arincDateFormatter dateFromString:dateString];

    if(!date)NSLog(@"PARSING arincDateString:'%@' -> (NSDate*)%@ ",arincDateString,date);

    return date;
}
+ (NSString *)xmlStringFromDate:(NSDate *)date
{
    if( !date ) return nil;        // exit on nil date

    @autoreleasepool {
        NSString *dateString = [self.arincDateFormatter stringFromDate:date];

        // iOS5 does not use a ':' in the timeZone part but xml needs it
        // so allways add the xml-standard colon ':' into the timezone
        NSMutableString *string = [NSMutableString stringWithString:dateString];
        if( 22 < string.length ) {        // prevent crashing
            [string insertString:@":" atIndex:22];
        } else {
            NSLog(@"date output string too short:%d<22",string.length);
        }
        dateString = string;

        if(!dateString)
            NSLog(@"OUTPUT '%@' -> (NSString*)%@",date,dateString);
        return dateString;
    }
}

static NSDateFormatter *gXmlDateFormatter = nil; // lazy init + (NSDateFormatter *)xmlDateFormatter { // e.g. updateDateTime="2012-09-18T11:06:19+00:00" if (gXmlDateFormatter == nil) { // prepare for parsinf Arinc-ISO-XML-dates input gXmlDateFormatter = [[NSDateFormatter alloc] init]; gXmlDateFormatter = [NSTimeZone timeZoneForSecondsFromGMT:0]; gXmlDateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; gXmlDateFormatter.dateFormat = @"yyyy'-'MM'-'dd'T'HH':'mm':'ssZZZZZ"; // only parsing! in iOS 6 (iOS5 will parse nil) // gXmlDateFormatter.dateFormat = @"yyyy'-'MM'-'dd'T'HH':'mm':'ssZ"; // all iOS but with NO colons in timeZone (add/remove) } NSLog(@"gXmlDateFormatter:%@",gXmlDateFormatter); return gXmlDateFormatter; } // there's a problem with the above dateformater and iOS5 creating nil-results + (NSDate *)dateFromXMLString:(NSString *)arincDateString { NSString *dateString = arincDateString; // xmlDateStrings may contain a ':' in the timezone part. iOS and Unicode DO NOT // so always remove the xml-standard colon ':' from the timezone to make it iOS/Unicode compatible // xml: http://www.w3schools.com/schema/schema_dtypes_date.asp // iOS: http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns) NSRange zRange = NSMakeRange(arincDateString.length-3, 1); dateString = [arincDateString stringByReplacingOccurrencesOfString:@":" withString:@"" options:0 range:zRange]; NSDate *date = [self.arincDateFormatter dateFromString:dateString]; if(!date)NSLog(@"PARSING arincDateString:'%@' -> (NSDate*)%@ ",arincDateString,date); return date; } + (NSString *)xmlStringFromDate:(NSDate *)date { if( !date ) return nil; // exit on nil date @autoreleasepool { NSString *dateString = [self.arincDateFormatter stringFromDate:date]; // iOS5 does not use a ':' in the timeZone part but xml needs it // so allways add the xml-standard colon ':' into the timezone NSMutableString *string = [NSMutableString stringWithString:dateString]; if( 22 < string.length ) { // prevent crashing [string insertString:@":" atIndex:22]; } else { NSLog(@"date output string too short:%d<22",string.length); } dateString = string; if(!dateString) NSLog(@"OUTPUT '%@' -> (NSString*)%@",date,dateString); return dateString; } }