Cocoa中NSString到NSDate的处理

原文地址:http://www.lianxu.me/blog/2012/03/14/speed-up-nsdateformatter/

如果程序中大量用到NSString转NSDate的代码,不推荐使用NSDateFormatter格式化, 它的速度非常慢。这篇文章介绍如何解决这种情况。

- (NSDate *)dateFromString:(NSString *)string {
    if (!string) {
        return nil;
    }
    //Wed Mar 14 16:40:08 +0800 2012
    static NSDateFormatter *dateformatter=nil;
    if(dateformatter==nil){
        dateformatter = [[NSDateFormatter alloc] init];
        NSTimeZone *tz = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
        [dateformatter setTimeZone:tz];
        [dateformatter setDateFormat:@"EEE MMM dd HH:mm:ss Z yyyy"];
    }
    return [dateformatter dateFromString:string];
}

由于NSDateFormatter内部代码原因,所以格式化字符串代价很大。直接使用NSDateFormatter绝对不是很好的选择,如果你的程序遇到了很多格式时间的代码更是如此。
根据这篇博客 How to Drastically Improve Your App with an Afternoon and Instruments 编写c代码格式化时间字符串速度会提高不少。

- (NSDate *)dateFromISO8601String:(NSString *)string {
    if (!string) {
        return nil;
    }

    struct tm tm;
    time_t t;

    strptime([string cStringUsingEncoding:NSUTF8StringEncoding], "%Y-%m-%dT%H:%M:%S%z", &tm);
    tm.tm_isdst = -1;
    t = mktime(&tm);

    return [NSDate dateWithTimeIntervalSince1970:t + [[NSTimeZone localTimeZone] secondsFromGMT]];
}

其实直接字符串处理后利用NSCalendar和NSDateComponents可以更快。

- (NSDate*)dateFromString:(NSString *)string;
{
    if (!string) {
        return nil;
    }
    //Wed Mar 14 16:40:08 +0800 2012
    static NSCalendar *gregorian=nil;
    static NSDateComponents comps=nil;
    if (gregorian==nil) {
        gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
        comps = [[NSDateComponents alloc] init];
    }

    NSArray *a=[string componentsSeparatedByString:@" "];
    if ([a count]==6) {
        [comps setYear:[[a objectAtIndex:5] intValue]];
        int mon=0;
        NSString *m=[a objectAtIndex:1];
        if ([m isEqualToString:@"Jan"]) {
            mon=1;
        }
        else if ([m isEqualToString:@"Feb"]) {
            mon=2;
        }
        else if ([m isEqualToString:@"Mar"]) {
            mon=3;
        }
        else if ([m isEqualToString:@"Apr"]) {
            mon=4;
        }
        else if ([m isEqualToString:@"May"]) {
            mon=5;
        }
        else if ([m isEqualToString:@"Jun"]) {
            mon=6;
        }
        else if ([m isEqualToString:@"Jul"]) {
            mon=7;
        }
        else if ([m isEqualToString:@"Aug"]) {
            mon=8;
        }
        else if ([m isEqualToString:@"Sep"]) {
            mon=9;
        }
        else if ([m isEqualToString:@"Oct"]) {
            mon=10;
        }
        else if ([m isEqualToString:@"Nov"]) {
            mon=11;
        }
        else if ([m isEqualToString:@"Dec"]) {
            mon=12;
        }
        [comps setMonth:mon];
        [comps setDay:[[a objectAtIndex:2] intValue]];

        @try {
            NSString *time=[a objectAtIndex:3];
            [comps setHour:[[time substringWithRange:NSMakeRange(0, 2)] intValue]];
            [comps setMinute:[[time substringWithRange:NSMakeRange(3, 2)] intValue]];
            [comps setSecond:[[time substringWithRange:NSMakeRange(6, 2)] intValue]];
        }
        @catch (NSException *exception) {
        }
        @finally {
        }

        return [gregorian dateFromComponents:comps];
    }
    return [NSDate date];
}

可以看到单独解析字符串的方法,虽然代码要长,但实际上它的速度是最快的。

原文地址:https://www.cnblogs.com/appwgh/p/2517461.html