【问题标题】:Getting NSDate from JSON generated by WCF REST service从 WCF REST 服务生成的 JSON 获取 NSDate
【发布时间】:2012-09-25 18:27:59
【问题描述】:

以下代码有效,但感觉很脏。有没有更标准的方法将带有偏移量的纪元日期转换为 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;
}

【问题讨论】:

    标签: xcode nsdate wcf-rest epoch


    【解决方案1】:

    试试这个 the original gist

     @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
    

    【讨论】:

    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
    • 很公平。我有点简洁。 :)
    【解决方案2】:

    // /日期(-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-02-18
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    相关资源
    最近更新 更多