【问题标题】:NSDateFormatter not working for single hard coded dateNSDateFormatter 不适用于单个硬编码日期
【发布时间】:2013-12-03 06:02:50
【问题描述】:

我正在使用以下代码从 NSString 中检索日期和年份。我在 NSLog 语句中打印它们。

NSDate *dateC= [[[NSDate alloc] init] autorelease];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setLocale:[NSLocale currentLocale]];
[dateFormat setDateFormat:@"MM/dd/yyyy HH:mm"];
dateC = [dateFormat dateFromString:@"04/15/2009 00:00"];  // Only this date gives null date.
[dateFormat setDateFormat:@"MMM dd, yyyy"];
NSLog(@"date = %@",[dateFormat stringFromDate:dateC]);

NSCalendar* calendar = [NSCalendar autoupdatingCurrentCalendar];
NSDateComponents* components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:dateC];
NSLog(@"year =%d",[components year]);
[dateFormat release];

此代码适用于除代码中提及的日期之外的每个日期。
输出应为:

日期 = 2009 年 4 月 15 日
年份 =2009

但输出是:

date = (null)
年份 =2001

请帮助我为什么会出现这种奇怪的行为?
注意:我使用的是 Xcode 4.6.2 和 iOS 6.1

【问题讨论】:

  • 我试过你的代码它也适用于硬编码日期。我的日志为:日期 = 2009 年 4 月 15 日,年份 =2009
  • 我试过了,它对我有用。问题,为什么是 dateC 的 alloc/init/autorelase?
  • 我总是得到这个:-[__NSCFCalendar components:fromDate:]: date cannot be nil 我的意思是真的,你认为这个操作对于一个 nil 日期应该意味着什么?暂时避免了一个例外。此投诉将报告其中一些错误,然后进一步的违规行为将简单地默默地执行 nil 导致的任何随机事情。
  • 它在 Xcode 5.0.1 iOS7 上运行良好: NSDate *dateC= [[NSDate alloc] init]; NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; [dateFormat setLocale:[NSLocale currentLocale]]; [dateFormat setDateFormat:@"MM/dd/yyyy HH:mm"]; dateC = [dateFormat dateFromString:@"04/15/2009 00:00"]; // 只有这个日期给出空日期。 NSLog(@"date = %@",dateC);
  • 几乎可以肯定它是您的语言环境 - 尝试使用像这样的语言环境 "[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]" 和/或日历 [dateFormat setCalendar:[[NSCalendar alloc] initWithCalendarIdentifier :NSGregorianCalendar]]

标签: ios iphone nsdate nsdateformatter nsdatecomponents


【解决方案1】:

请试试这个确切的代码。另请注意 Date Formatters GuideFixed Formats 下的部分,链接到 NSDateFormatter 类描述中。

// NSDateFormatter Class Description says:
// Note that although setting a format string (setDateFormat:) in principle specifies an
// exact format, in practice it may nevertheless also be overridden by a user’s
// preferences—see Data Formatting Guide for more details.
NSLocale *locale;

NSLocale *curLocale = [NSLocale currentLocale];
NSLocale *usaLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
if([curLocale.localeIdentifier isEqualToString:usaLocale.localeIdentifier]) {
    locale = [[NSLocale alloc] initWithLocaleIdentifier:usaLocale.localeIdentifier];
    NSLog(@"Created a new one");
} else {
    NSLog(@"USed the old one");
    locale = usaLocale;
}
assert(locale);

NSDate *dateC= [[NSDate alloc] init];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setLocale:locale];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
assert(calendar);
[dateFormat setCalendar:calendar];
[dateFormat setDateFormat:@"MM/dd/yyyy HH:mm"];

dateC = [dateFormat dateFromString:@"04/15/2009 00:00"];  // O
NSLog(@"DATE: %@", dateC);

【讨论】:

  • Heyyyyy Dav... 你做了魔法。它现在工作..真正的感谢。经验真的很重要。
  • @ShahidIqbal,那么您收到新语言环境的日志消息还是使用旧语言环境?没有魔法 - 我只是反复阅读文档!
  • 大卫。我放了 NSLog 语句来检查我当前的语言环境标识符,它显示了“en_US”。因此,如果语句被执行并显示“创建一个新的”消息。但我发现,问题不在于语言环境。问题是,我没有将 Calendar 设置为 NSDateFormatter setCalendar 方法。所以只需添加 [dateFormat setCalendar:[NSCalendar autoupdatingCurrentCalendar]];我的代码中的行成功了。但是再次感谢,我可以通过查看您的代码来做到这一点。
  • 如果您阅读文档,用户可以更改其设备上的日期格式并打破固定格式转换,从而打破新的语言环境。我不知道这是否只是一个 OSX 问题,或者也可能发生在 ios 中。无论如何,按照上面的方式进行操作可能更安全。
【解决方案2】:

如果显示不同的小时,您可能需要设置默认时区(这仅在 ios7 之后发生)

[dateFormat setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多