在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:×tampString]; 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格式后,使用NSDateFormatter
的dateFromString:
方法。
– (的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]; } }
}