给出以下代码:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"];
NSLog(@"Date from String: %@", [formatter dateFromString:@"2013-09-08T00:36:40"]);
日志产生:字符串中的日期:( null)
对于来自同一来源的其他字符串,它可以正常工作,但我没有看到为什么在这种情况下会失败。
有人可以启发我吗?
更新:我已按如下方式更新了代码,但仍然失败:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"];
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
[formatter setLocale:locale];
NSDate *date = nil;
NSError *error = nil;
[formatter getObjectValue:&date
forString:@"2013-09-08T00:36:40"
range:NULL
error:&error];
NSLog(@"Date from String: %@", date);
NSLog(@"Error: %@", error);
输出: 2014-03-31 15:27:01.697无标题[30859:507]字符串日期:(null) 2014-03-31 15:27:01.710无标题[30859:507]错误:错误域= NSCocoaErrorDomain代码= 2048"值“2013-09-08T00:36:40”无效。" UserInfo = 0x7f89d8e04cd0 {NSInvalidValue = 2013-09-08T00:36:40}
更新2:经过一些游戏,我发现我的时区是它失败的原因(我不明白为什么,但它只在我的时区下失败)
以下代码失败:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"];
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
[formatter setLocale:locale];
[formatter setTimeZone:[NSTimeZone timeZoneWithName:@"America/Santiago"]];
NSDate *date = nil;
NSError *error = nil;
[formatter getObjectValue:&date
forString:@"2013-09-08T00:36:40"
range:NULL
error:&error];
NSLog(@"Date from String: %@", date);
NSLog(@"Error: %@", error);
有任何建议可以解决吗?
答案 0 :(得分:2)
根据http://www.timeanddate.com/time/zone/chile/santiago,夏令时 时区“America / Santiago”于2013年9月8日星期日00:00开始,这意味着时钟已经调整一小时到太阳,9月8日,01:00。
因此当天不存在时间“00:36:40”。这就是原因 转换失败。
可能的解决方案是使用给定的组件填充NSDateComponents
然后拨打dateFromComponents
:
NSCalendar *cal = [NSCalendar currentCalendar];
[cal setTimeZone:[NSTimeZone timeZoneWithName:@"America/Santiago"]];
NSDateComponents *comp = [[NSDateComponents alloc] init];
comp.year = 2013;
comp.month = 9;
comp.day = 8;
comp.hour = 0;
comp.minute = 36;
comp.second = 40;
NSDate *d = [cal dateFromComponents:comp];
NSLog(@"Date from components: %@", d); // 2013-09-08 04:36:40 +0000
NSString *s = [formatter stringFromDate:d];
NSLog(@"String from date: %@", s); // 2013-09-08T01:36:40
这给出了所有“有效”日期字符串的相同日期,也是一个明智的结果 对于夏令时转换期间的“无效”日期字符串。
答案 1 :(得分:1)
错误是由于智利区域下的日期不存在(由于DST更改)。
虽然NSDateFormatter返回nil是正确的,因为它不存在。告诉用户“文件是在您的时区从未经历过的时间内创建的”是不可行的。
解决方案(适用于任何其他DST区域)是设置一个时区,就像没有DST的当前时区一样。
NSString *dateString = ...; //Assume it is defined
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"];
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
[formatter setLocale:locale];
//Date formatting might fail because of Daylight Saving Timezones and the like. So, we force the timezone to one just like it where the date always exist.
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:[[NSTimeZone localTimeZone] secondsFromGMT]]];
NSDate *date = nil;
NSError *error = nil;
[formatter getObjectValue:&date
forString:dateString
range:NULL
error:&error];
同样,这在技术上并不正确,但可以用于显示目的。