iOS RestKit日期解析

4

在一个旧的iOS项目中,我需要解析日期,其格式为dd/MM/yyyy,因此我将下面这些代码放在我的AppDelegate的静态方法中,并且它按预期工作。

// Set the Dateformatter for the Dates returned by Knowledge tt/mm/yyyy
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"dd/MM/yyyy"];
[[RKValueTransformer defaultValueTransformer] insertValueTransformer:dateFormatter atIndex:0];

然而,在实际项目中,我的日期格式略有不同dd.MM.yyyy,因此我使用了相同的代码行,只是更改了日期格式,但日期没有被解析。

对于这个日期"ExamDate":"20.06.2014",在解析后我得到(NSDate *) _examDate = 0x08f7dcd0 2014-01-01 01:00:00 CET,但我无法理解为什么。

更新: 我用以下代码进行了小测试:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"dd.MM.yyyy"];
NSDate *date = [dateFormatter dateFromString:@"20.06.2014"];
DLog(@"Date: %@", date);

并在日志中得到:日期:2014-06-19 22:00:00 +0000

1个回答

7

看起来你的时区是GMT偏移量为-2:00。将你的时区设置为0 GMT以正确打印时间。通常我们只是在传递日期时使用Unix时间戳,这样就可以避免此类问题。

dateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];

由于你的问题似乎出现在 RestKit 的解析过程中,所以需要使用自己的日期解析器。你可以通过安装 RestKit 调用的值转换器来实现这一点,它是在映射数据时使用的。

以下是一个可以用来实现你想要的功能的样例:

[RKObjectMapping alloc]; // This ensures you will actually insert at index 0!

[RKValueTransformer.defaultValueTransformer
 insertValueTransformer:
 [RKBlockValueTransformer
  valueTransformerWithValidationBlock:^BOOL(__unsafe_unretained Class inputValueClass, __unsafe_unretained Class outputValueClass) {
      return (([inputValueClass isSubclassOfClass:[NSDate class]] && [outputValueClass isSubclassOfClass:[NSString class]]) ||
              ([inputValueClass isSubclassOfClass:[NSString class]] && [outputValueClass isSubclassOfClass:[NSDate class]]));
  }
  transformationBlock:^BOOL(id inputValue, __autoreleasing id *outputValue, __unsafe_unretained Class outputClass, NSError *__autoreleasing *error) {
      RKValueTransformerTestInputValueIsKindOfClass(inputValue, (@[ [NSString class], [NSDate class] ]), error);
      RKValueTransformerTestOutputValueClassIsSubclassOfClass(outputClass, (@[ [NSString class], [NSDate class] ]), error);
      if ([inputValue isKindOfClass:[NSString class]]) {
          // We're mapping from a string to a date.
          // You can add your formatter here.
          // Below is mine for mapping from Unix Time to an NSDate.
          NSString* input = inputValue;
          *outputValue = [NSDate dateWithTimeIntervalSince1970:input.integerValue];
      } else if ([inputValue isKindOfClass:[NSDate class]]) {
          // We're mapping from a date to a string.
          // You can add your formatter here (if needed).
          // Below is mine for mapping from an NSDate to Unix Time.
          NSDate* input = inputValue;
          *outputValue = @([input timeIntervalSince1970]);
      }
      return YES;
  }]
 atIndex:0]; // Insert at index 0 so your formatter is always used over the default one.

另外,看起来RestKit有自己的NSDateFormatter类别,可以支持将其添加为RKValueTransformer。您可以尝试以下操作:

[RKObjectMapping alloc]; // This ensures you will actually insert at index 0!
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"dd.MM.yyyy"];
dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
[RKDefaultValueTransformer insertValueTransformer:dateFormatter atIndex:0];

你说得对...这解决了我的日期格式化示例问题,但仍然没有自动解析RestKit中的日期,我仍然得到2014年1月1日的日期。 - Hons
你使用的是哪个版本的RestKit?@Hons - Sandy Chapman
@Hons,既然你正在使用0.23.1版本,你可以使用RKValueTransformer。我已经将其中一个粘贴到了我的答案中。在我的注释处,您需要添加自己的格式化代码,但这应该能让您走上正确的轨道。 - Sandy Chapman
我将你的代码添加到我的项目中。第一个块是验证,对于每个属性都会调用它,对于我的日期它返回YES,但第二个块从未被调用。 - Hons
@Hons 这很奇怪。如果它返回的是YES,并且你将其插入到索引0,那么它应该使用你的转换块。尝试移除RKValueTransformerTest...宏调用,看看是否有效。 - Sandy Chapman
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接