请原谅我,因为我对Objective C还不熟悉。
我从一个.NET网络服务获取的日期格式是 /Date(xxxxxxxxxxxxx-xxxx)/。我正在寻找如何最好地将其解析为NSDate对象的方向。我尝试对其使用dateWithTimeIntervalSince1970,但返回的是1969年的日期,而我知道它应该是2006年的日期。
寻求关于正确处理JSON日期的指导。
提前致谢!
请原谅我,因为我对Objective C还不熟悉。
我从一个.NET网络服务获取的日期格式是 /Date(xxxxxxxxxxxxx-xxxx)/。我正在寻找如何最好地将其解析为NSDate对象的方向。我尝试对其使用dateWithTimeIntervalSince1970,但返回的是1969年的日期,而我知道它应该是2006年的日期。
寻求关于正确处理JSON日期的指导。
提前致谢!
我刚为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;
}
我在使用不支持日期格式的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];
}
我并没有像上面的回答那样处理日期格式中的附加部分,所以我没有进行过处理。同时我也没有进行错误捕获,这对我来说都是新的。
我之前发现使用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;
}
节省大量手动字符串处理,使代码更加简洁。
- (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 解决方案。如果没有,我可能会保留这个解决方案或寻找在 .NET 中更改序列化格式的方法。
编辑:
关于 JSON DateTime 格式...... 如果您可以控制服务,则最好将日期转换为字符串放在 DataContract 对象中。
格式化为 RFC1123 现在对我来说似乎是一个不错的想法。因为我可以轻松地使用 NSDateFormatter 进行格式化。
Rick Strahl 的引用:
JavaScript 没有日期文字,Microsoft 设计了一种定制的日期格式,它实际上是一个标记化的字符串。该格式是一个被编码的字符串,包含标准的 new Date(milliseconds since 1970) 值。
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];
在设置日期格式之后,使用NSDateFormatter
的dateFromString:
方法。
-(NSString*)convertToUTCTime:(NSString*)strDate{
-(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 minutes = (ti / 60) % 60; NSInteger hours = (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];
}
}
}
if ((NSNull *)string == [NSNull null]) return nil;
- nevan king