在iPhone上parsingJSONdate

原谅我,因为我是新来的客观C.

我在/ Date(xxxxxxxxxxxxx-xxxx)/格式中从.NET webservice获取date。 我正在寻找如何最好的parsing这个NSDate对象的一些方向。 我已经尝试使用dateWithTimeIntervalSince1970上,但它回来与1969年的date,我知道是在2006年的date。

寻找适当的方式来处理JSONdate的一些方向。

提前致谢!

作为学习Objective-C的.NET程序员,当我尝试使用.Net WebService时,我遇到了同样的问题。

起初我以为我可以使用NSDateFormatter …我在这里find了一个很好的参考符号,但是我很快意识到我需要将数字从毫秒转换为秒。

我写了代码来做到这一点…我仍然在学习Obj-C,但我不认为这应该是这么难…

- (NSDate *) getJSONDate{ NSString* header = @"/Date("; uint headerLength = [header length]; NSString* timestampString; NSScanner* scanner = [[NSScanner alloc] initWithString:self]; [scanner setScanLocation:headerLength]; [scanner scanUpToString:@")" intoString:&timestampString]; NSCharacterSet* timezoneDelimiter = [NSCharacterSet characterSetWithCharactersInString:@"+-"]; NSRange rangeOfTimezoneSymbol = [timestampString rangeOfCharacterFromSet:timezoneDelimiter]; [scanner dealloc]; if (rangeOfTimezoneSymbol.length!=0) { scanner = [[NSScanner alloc] initWithString:timestampString]; NSRange rangeOfFirstNumber; rangeOfFirstNumber.location = 0; rangeOfFirstNumber.length = rangeOfTimezoneSymbol.location; NSRange rangeOfSecondNumber; rangeOfSecondNumber.location = rangeOfTimezoneSymbol.location + 1; rangeOfSecondNumber.length = [timestampString length] - rangeOfSecondNumber.location; NSString* firstNumberString = [timestampString substringWithRange:rangeOfFirstNumber]; NSString* secondNumberString = [timestampString substringWithRange:rangeOfSecondNumber]; unsigned long long firstNumber = [firstNumberString longLongValue]; uint secondNumber = [secondNumberString intValue]; NSTimeInterval interval = firstNumber/1000; return [NSDate dateWithTimeIntervalSince1970:interval]; } unsigned long long firstNumber = [timestampString longLongValue]; NSTimeInterval interval = firstNumber/1000; return [NSDate dateWithTimeIntervalSince1970:interval]; } 

希望有人可以提供更好的Obj-C解决scheme。 如果没有,我可以保持这个或寻找一种方式来改变在.NET中的序列化格式

编辑:

关于这个JSON DateTime格式…如果你有任何控制服务,最好把date转换成你的DataContract对象中的一个string。

格式化为RFC1123对我来说似乎是个好主意。 正如我可以轻松地使用NSDateFormatter捡起它。

来自Rick Strahl的引用

没有JavaScriptdate文字,微软devise了一个自定义的date格式,基本上是一个标记的string。 格式是一个编码的string,包含标准的新Date(自1970年以来的毫秒)值。

我只是写这个iOS 4.0 +(因为它使用NSRegularExpression)。 它处理有或没有时区偏移的date。 似乎工作得很好,你怎么看?

 + (NSDate *)mfDateFromDotNetJSONString:(NSString *)string { static NSRegularExpression *dateRegEx = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ dateRegEx = [[NSRegularExpression alloc] initWithPattern:@"^\\/date\\((-?\\d++)(?:([+-])(\\d{2})(\\d{2}))?\\)\\/$" options:NSRegularExpressionCaseInsensitive error:nil]; }); NSTextCheckingResult *regexResult = [dateRegEx firstMatchInString:string options:0 range:NSMakeRange(0, [string length])]; if (regexResult) { // milliseconds NSTimeInterval seconds = [[string substringWithRange:[regexResult rangeAtIndex:1]] doubleValue] / 1000.0; // timezone offset if ([regexResult rangeAtIndex:2].location != NSNotFound) { NSString *sign = [string substringWithRange:[regexResult rangeAtIndex:2]]; // hours seconds += [[NSString stringWithFormat:@"%@%@", sign, [string substringWithRange:[regexResult rangeAtIndex:3]]] doubleValue] * 60.0 * 60.0; // minutes seconds += [[NSString stringWithFormat:@"%@%@", sign, [string substringWithRange:[regexResult rangeAtIndex:4]]] doubleValue] * 60.0; } return [NSDate dateWithTimeIntervalSince1970:seconds]; } return nil; } 

我在同一条船上,同时使用不支持date格式的JSON框架,因为它不是官方的JSON。 我的来源是使用JSON.Net构build的API。 这就是我想到的:

 - (NSDate*) getDateFromJSON:(NSString *)dateString { // Expect date in this format "/Date(1268123281843)/" int startPos = [dateString rangeOfString:@"("].location+1; int endPos = [dateString rangeOfString:@")"].location; NSRange range = NSMakeRange(startPos,endPos-startPos); unsigned long long milliseconds = [[dateString substringWithRange:range] longLongValue]; NSLog(@"%llu",milliseconds); NSTimeInterval interval = milliseconds/1000; return [NSDate dateWithTimeIntervalSince1970:interval]; } 

我没有date格式的附加部分,所以我没有像上面的答案那样处理。 没有错误,这一点对我来说都是新的。

我实际上发现NSRegularExpression的片段非常有用,直到我想出了另一个使用NSCharecterSet解决毫秒的解决scheme。

 + (NSDate*) dateFromJSONString:(NSString *)dateString { NSCharacterSet *charactersToRemove = [[ NSCharacterSet decimalDigitCharacterSet ] invertedSet ]; NSString* milliseconds = [dateString stringByTrimmingCharactersInSet:charactersToRemove]; if (milliseconds != nil && ![milliseconds isEqualToString:@"62135596800000"]) { NSTimeInterval seconds = [milliseconds doubleValue] / 1000; return [NSDate dateWithTimeIntervalSince1970:seconds]; } return nil; } 

节省了大量的手动string处理,使代码更清洁。

理论:MS自1970年以来以JSON编码C#date时间为毫秒。解决scheme:

 NSString* dateAsString = @"/Date(1353720343336+0000)/"; dateAsString = [dateAsString stringByReplacingOccurrencesOfString:@"/Date(" withString:@""]; dateAsString = [dateAsString stringByReplacingOccurrencesOfString:@"+0000)/" withString:@""]; unsigned long long milliseconds = [dateAsString longLongValue]; NSTimeInterval interval = milliseconds/1000; NSDate* date = [NSDate dateWithTimeIntervalSince1970:interval]; 

这是我能想到的最短的解决scheme。

设置date格式后,使用NSDateFormatterdateFromString:方法。

– (的NSString *)convertToUTCTime:(的NSString *)strDate {

 NSDate *currentDate = [NSDate date]; myDate = [commonDateFormatter dateFromString: strDate]; NSTimeInterval distanceBetweenDates = [currentDate timeIntervalSinceDate:myDate]; return [self stringFromTimeInterval:distanceBetweenDates]; 

} – (NSString *)stringFromTimeInterval:(NSTimeInterval)interval {NSInteger ti =(NSInteger)interval; NSInteger分钟数=(ti / 60)%60; NSInteger小时=(ti / 3600);

 if (hours > 24) { NSInteger days = hours/24; if (days > 30) { NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"EEE d MMM, h:mm a"]; //[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"IST"]]; NSString *daydate = [dateFormatter stringFromDate:myDate]; return daydate; } else{ return [NSString stringWithFormat:@" %2ldd",(long)days]; } }else{ if (hours == 0 && minutes < 1) { return [NSString stringWithFormat:@"Today"]; } else if (hours == 0 && minutes < 60){ return [NSString stringWithFormat:@"%2ldm ",(long)minutes]; } else{ return [NSString stringWithFormat:@" %2ldh",(long)hours]; } } 

}