问题
In an old iOS project I had to parse dates that come in the format dd/MM/yyyy
so I put these lines in a static method of my AppDelegate and it worked as expected
// 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];
However in the actual projects my dates come in a slightly different format dd.MM.yyyy
, so I used the same lines of code, just switched the Date format, but the date is not parsed.
For this date "ExamDate":"20.06.2014"
I get (NSDate *) _examDate = 0x08f7dcd0 2014-01-01 01:00:00 CET
after parsing and I can't understand why.
Update: I made a small test with this code:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"dd.MM.yyyy"];
NSDate *date = [dateFormatter dateFromString:@"20.06.2014"];
DLog(@"Date: %@", date);
and got in the log: Date: 2014-06-19 22:00:00 +0000
回答1:
It looks like your in a timezone with a GMT offset of -2:00. Set your timezone to 0 GMT to have it printed correctly. What we usually do is just use unix time when passing around dates so we can avoid this sort of issue.
dateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
Since your problem appears to be in RestKit's parsing you'll need to use your own date parser. You can do this by installing what RestKit calls a Value Transformer which is what it uses when mapping data.
Here's one that you can work with to achieve what you want:
[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.
Alternatively, it looks like RestKit has it's own NSDateFormatter category which adds support for adding it as an RKValueTransformer. You should be able to try something like this:
[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];
来源:https://stackoverflow.com/questions/24407436/ios-restkit-date-parsing