use*_*517 36 iphone datetime json objective-c
请原谅我,因为我是Objective C的新手.
我从/ Date(xxxxxxxxxxxxx-xxxx)/格式的.NET Web服务中获取日期.我正在寻找一些关于如何最好地将其解析为NSDate对象的方向.我已经尝试过对它使用dateWithTimeIntervalSince1970,但它在1969年的日期回来了,我所知道的日期是在2006年.
寻找处理JSON日期的正确方法的一些方向.
提前致谢!
jas*_*ori 47
我刚刚为iOS 4.0+写了这个(因为它使用了NSRegularExpression).它处理带或不带时区偏移的日期.似乎工作得很好,你怎么看?
+ (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;
}
Run Code Online (Sandbox Code Playgroud)
tox*_*xaq 18
当我使用不支持日期格式的json-framework时,我在同一条船上,因为它不是官方JSON.我的源代码来自使用JSON.Net构建的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];
}
Run Code Online (Sandbox Code Playgroud)
我没有你所做的日期格式的附加部分,所以我没有像上面的答案那样处理.没有错误捕获,这对我来说都是新的.
Meh*_*fuz 11
我实际上发现NSRegularExpression的片段非常有用,直到我想出了另一个使用NSCharecterSet来解决毫秒的解决方案.
+ (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;
}
Run Code Online (Sandbox Code Playgroud)
节省了大量的手动字符串处理,使代码更加清晰.
作为一名学习Objective-C的.NET程序员,当我尝试使用.Net WebService时,我遇到了同样的问题.
起初我以为我可以使用NSDateFormatter ...我在这里找到了一个非常好的参考符号,但我很快意识到我需要将数字从毫秒转换为秒.
我写了代码来做它...我还在学习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];
}
Run Code Online (Sandbox Code Playgroud)
希望有人能提供更好的Obj-C解决方案.如果不是,我可以保留它或寻找一种方法来改变.NET中的序列化格式
编辑:
关于JSON DateTime格式...如果您对服务有任何控制,最好将日期转换为DataContract对象中的字符串.
格式化为RFC1123对我来说似乎是一个好主意.因为我可以使用NSDateFormatter轻松地获取它.
没有JavaScript日期文字,Microsoft设计了一个自定义日期格式,本质上是一个标记字符串.格式是一个编码的字符串,包含标准的新Date(自1970年以来的毫秒)值.
小智 5
理论:自1970年以来,MS将JSON中的C#DateTime编码为毫秒.解决方案:
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];
Run Code Online (Sandbox Code Playgroud)
这是我能想到的最短的解决方案.