IOS 6数据格式化程序
请帮助我在IOS6上使用dateformatter,请参阅下面的代码IOS 6数据格式化程序,ios,ios6,nsdateformatter,Ios,Ios6,Nsdateformatter,请帮助我在IOS6上使用dateformatter,请参阅下面的代码 NSString stringDate = @"12/31/9999"; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init]; [dateFormatter setDateFormat:@"MM/dd/yyyy"]; NSDate *dateCheck = [dateFormatter dateFromString:stringDate]; NS
NSString stringDate = @"12/31/9999";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:@"MM/dd/yyyy"];
NSDate *dateCheck = [dateFormatter dateFromString:stringDate];
NSLog(@"Date = %@", dateCheck);
输出为
Date = 1999-12-31 08:00:00 +0000
这是将字符串日期转换为日期12/31/9999时的输出
从以前版本的IOS6中,输出为
Date = 9999-12-31 08:00:00 +0000 // Correct
我为公司的企业应用程序修复了这个问题 对于使用已知格式字符串的日期格式化程序(如我们用于从sqlite数据库解析日期的字符串),它应该解决这个问题 但是,它不会修复:
#import <Foundation/Foundation.h>
@interface NSDateFormatter (HotFix)
- (NSDate*)dateFromString:(NSString *)string;
@end
#导入
@接口NSDateFormatter(修补程序)
-(NSDate*)dateFromString:(NSString*)字符串;
@结束
NSDateFormatter+HotFix.m
#import "NSDateFormatter+HotFix.h"
#import <objc/runtime.h>
@implementation NSDateFormatter (HotFix)
- (NSDate*)dateFromString:(NSString *)string
{
if (!string) return nil;
//HACK: Use the original implementation
void* baseFormatter = nil;
object_getInstanceVariable(self, "_formatter", &baseFormatter);
if (!baseFormatter) return nil;
//Use the underlying CFDateFormatter to parse the string
CFDateRef rawDate = CFDateFormatterCreateDateFromString(kCFAllocatorDefault, (CFDateFormatterRef)baseFormatter, (CFStringRef)string, NULL);
NSDate* source = (NSDate*)rawDate;
//We do not support lenient parsing of dates (or styles), period.
if (source && !self.isLenient && self.dateStyle == NSDateFormatterNoStyle && self.timeStyle == NSDateFormatterNoStyle)
{
//If it worked, then find out if the format string included a year (any cluster of 1 to 5 y characters)
NSString* format = [self dateFormat];
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@"y{1,5}" options:NSRegularExpressionCaseInsensitive error:NULL];
NSArray* matches = [regex matchesInString:format options:0 range:NSMakeRange(0, [format length])];
if ([matches count] > 0)
{
for (NSTextCheckingResult* result in matches)
{
//Check for the y grouping being contained within quotes. If so, ignore it
if (result.range.location > 0 && result.range.location + result.range.length < [format length] - 1)
{
if ([format characterAtIndex:result.range.location - 1] == '\'' &&
[format characterAtIndex:result.range.location + result.range.length + 1] == '\'') continue;
}
NSString* possibleYearString = [string substringWithRange:result.range];
NSInteger possibleYear = [possibleYearString integerValue];
if (possibleYear > 3500)
{
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* dateComp = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit fromDate:source];
dateComp.year = possibleYear;
return [calendar dateFromComponents:dateComp];
}
}
}
}
return [source autorelease];
}
@end
#导入“NSDateFormatter+HotFix.h”
#进口
@实现NSDateFormatter(修补程序)
-(NSDate*)dateFromString:(NSString*)string
{
如果(!string)返回nil;
//HACK:使用原始实现
void*baseFormatter=nil;
对象\u getInstanceVariable(self、\u formatter、&baseFormatter);
如果(!baseFormatter)返回nil;
//使用底层的CFDateFormatter来解析字符串
CFDateRef rawDate=CFDateFormatterCreateDateFromString(kCFAllocatorDefault,(CFDateFormatterRef)baseFormatter,(CFStringRef)string,NULL);
NSDate*来源=(NSDate*)原始日期;
//我们不支持对日期(或样式)、句号进行宽松的解析。
if(source&&!self.islenent&&self.dateStyle==NSDateFormatterNoStyle&&self.timeStyle==NSDateFormatterNoStyle)
{
//如果有效,则找出格式字符串是否包含一年(任何1到5个y字符的集群)
NSString*格式=[self dateFormat];
NSRegularExpression*regex=[NSRegularExpression regular expressionwithpattern:@“y{1,5}”选项:nsregularexpressioncase不敏感错误:NULL];
NSArray*matches=[regex matchesInstalling:格式选项:0范围:NSMakerRange(0,[格式长度])];
如果([匹配计数]>0)
{
for(NSTextCheckingResult*匹配结果)
{
//检查引号中是否包含y分组。如果是,请忽略它
if(result.range.location>0&&result.range.location+result.range.length<[格式长度]-1)
{
如果([格式字符索引:result.range.location-1]='\''&&
[格式字符索引:result.range.location+result.range.length+1]=='\''继续;
}
NSString*possibleYearString=[string substringWithRange:result.range];
NSInteger possibleYear=[possibleYearString integerValue];
如果(可能大于3500)
{
NSCalendar*日历=[NSCalendar currentCalendar];
NSDateComponents*dateComp=[日历组件:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit fromDate:source];
dateComp.year=可能的年份;
返回[calendar dateFromComponents:dateComp];
}
}
}
}
返回[源自动释放];
}
@结束
它将替换NSDateFormatter的现有dateFromString方法。它的工作原理是尝试正常解析字符串,然后检查formatString是否包含一组年份格式字符。如果是,则手动提取年份并检查其是否大于3500。最后,如果是这种情况,它将重写输出以获得正确解析的年份
只要将它包含在您的项目中,它就会生效。您不需要将头导入到每个使用NSDateFormatter的文件中,只需在中编译.m即可修改该类。如果有任何其他类别更改了dateFromString:,则无法定义此类的效果
我希望这会有所帮助。关于iOS6日期格式化程序中可能存在的错误,还有其他报告,这似乎是一个错误。格式化程序似乎只能在未来1500年内使用(3512)哦,但是对于不同的格式,如MM dd yyyy,它不是1500年的间隔。我不理解这个评论,它与格式没有任何关系,只是你放在哪一年——当然9999是1500年以后的事了。如果您尝试3512,您将看到它是有效的,而3513不是。