1

以下代码有效,但感觉很脏。有没有更标准的方法将带有偏移的纪元日期转换为 NSDate?

- (NSDate *) dateFromJSONString: (NSString *) JSONString{
    //expects JSON from .NET WCF Service in epoch ticks, ex:
    //"timeScheduled":"\/Date(1348600140000+0100)\/"
    NSString *date = [[JSONString stringByReplacingOccurrencesOfString:@"/Date("         withString:@""] stringByReplacingOccurrencesOfString:@")/" withString:@""];
    NSString *offsetString = [date substringFromIndex:(date.length - 5)];

    //convert to seconds
    NSTimeInterval dateInterval = [date doubleValue] /1000;

    //gets offset value in seconds - +0100 -> 100 -> 1 -> 3600
    double offsetValue = ([offsetString doubleValue] / 100) * 60 * 60;
    if ([[offsetString substringToIndex:1] isEqualToString:@"+"]) {
        dateInterval = dateInterval + offsetValue;
    }
    else{
        dateInterval = dateInterval - offsetValue;
    }

    NSDate *retVal = [[NSDate alloc]initWithTimeIntervalSince1970:dateInterval];

    return retVal;
}
4

2 回答 2

3

试试这个 原来的要点

 @implementation NSDate (DotNetDates)

+(NSDate*) dateFromDotNet:(NSString*)stringDate{

 NSDate *returnValue;

if ([stringDate isMemberOfClass:[NSNull class]]) {
   returnValue=nil;
}
else  {
  NSInteger offset = [[NSTimeZone defaultTimeZone] secondsFromGMT];

  returnValue= [[NSDate dateWithTimeIntervalSince1970:
                   [[stringDate substringWithRange:NSMakeRange(6, 10)] intValue]]
                  dateByAddingTimeInterval:offset]; 
}

   return returnValue;

}
 -(NSString*) dateToDotNet{
 double timeSince1970=[self timeIntervalSince1970];
 NSInteger offset = [[NSTimeZone defaultTimeZone] secondsFromGMT];
 offset=offset/3600;
 double nowMillis = 1000.0 * (timeSince1970);
 NSString *dotNetDate=[NSString stringWithFormat:@"/Date(%.0f%+03d00)/",nowMillis,offset] ;
return  dotNetDate;
}


@end
于 2012-10-04T16:06:38.917 回答
0

// /日期(-422928000000+0100)/ 文档:

DateTime 值显示为 JSON 字符串,格式为“/Date(700000+0500)/”,其中第一个数字(在提供的示例中为 700000)是 GMT 时区的毫秒数,常规(非夏令时)自 1970 年 1 月 1 日午夜以来的时间。该数字可能为负数以表示较早的时间。示例中由“+0500”组成的部分是可选的,表示时间是本地类型的——也就是说,应该在反序列化时转换为本地时区。如果不存在,则将时间反序列化为 Utc。实际数字(本例中为“0500”)及其符号(+ 或 -)将被忽略。

NSTimeInterval 总是以秒为单位指定;它在 10,000 年的范围内产生亚毫秒精度。

+ (NSDate*) dateFromDotNet:(NSString *)stringDate{
    if(stringDate==(id)[NSNull null])
        return nil;
    NSInteger ix0= [stringDate rangeOfString:@"("].location;
    NSInteger ix1= [stringDate rangeOfString:@")"].location;
    if(ix0==NSNotFound || ix1==NSNotFound)
        @throw [NSException exceptionWithName:@"ExceptionName" reason:@"Invalid JSON data" userInfo:@{@"json":stringDate}];
    NSRange range= NSMakeRange(ix0+1, ix1-ix0);
    NSString *dateString= [stringDate substringWithRange:range];
    // dateString:  -422928000000+0100    
    NSCharacterSet *signs= [NSCharacterSet characterSetWithCharactersInString:@"+-"];
    range= [dateString rangeOfCharacterFromSet:signs option:NSBackwardSearch];
    // WCF will send 13 digit-long value for the time interval since 1970 (millisecond precision)
    // whereas iOS works with 10 digit-long values (second precision), hence the divide by 1000
    NSTimeInterval unixTime = [dateString doubleValue] / 1000;

    if(range.location!=NSNotFound){
        NSString *sign = [dateString substringWithRange:range];
        NSString *off  = [dateString substringFromIndex:range.location+1];
        // gets offset value in seconds -+0100 -> 100 -> 1 -> 3600
        double offset  = ([off doubleValue] / 100) * 60 * 60;
        if ([sign isEqualToString:@"+"])
            unixTime+= offset;
        else
            unixTime-= offset;
    }
    NSDate *date= [NSDate dateWithTimeIntervalSince1970:unixTime];
    return date;
}
于 2012-11-26T23:27:25.360 回答