【问题标题】:Why does my NSDateFormatter sometimes return an a.m. or p.m. with yyyyMMddHHmmssSSS?为什么我的 NSDateFormatter 有时会返回 a.m. 或 p.m.与 yyyyMMddHHmmssSSS?
【发布时间】:2011-10-27 16:29:30
【问题描述】:

有时我的代码会返回上午或下午。但不总是。大多数时候它只是返回我所期望的,类似于:20110815170852164

但其他时候它会返回:20100412010241 a.m.450

NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:@"yyyyMMddHHmmssSSS"];
NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];

这可能是什么原因造成的?用户 iPhone 上的特定日期/时间国家/地区设置?我把这个告诉了成千上万的人,大多数人都没有返回上午(这是预期的),但其他人是。为什么?

【问题讨论】:

标签: iphone objective-c xcode cocoa-touch ios4


【解决方案1】:

您描述的问题是一个已知错误。 Check out some discussion on the problem on stackoverflow,您可以在那里找到一些可能的解决方法。

这里是 huyz 对该错误的解释的摘录:

问题来自 NSDateFormatter 以某种方式“卡住”在用户手动选择的 12 或 24 小时时间模式。因此,如果法国用户手动选择 12 小时模式,并且应用程序请求 NSDateFormatter 以 24 小时格式“HHmm”输出时间,它实际上会以 12 小时格式接收时间,例如“01:00 PM”,好像应用程序改为请求“hhmm aa”。如果美国用户手动选择 24 小时模式,则会发生相反的情况:以 12 小时格式“hhmm aa”输出时间实际上会让您获得 24 小时格式的时间,例如“17:00”。

【讨论】:

  • 好吧,Apple 已经声明它不是一个“错误”,而是一个“功能”(在这种情况下更恰当地拼写为“feechure”)。
【解决方案2】:

没错。解决方案是显式设置日期格式化程序的区域设置,最好设置为 en_US_POSIX。查看this问题的最终答案。

【讨论】:

    【解决方案3】:

    我正在处理一个项目的数据共享功能,该功能高度依赖于我遇到相同问题时预先输入的值/结果。我实现了一个令人讨厌的小变通方法,将正确的日期时间以 24 小时格式保存到数据库中。

    解决方法很简单

    首先,我从设备获取本地日期:

    NSDate* now = [NSDate date];
    

    第二步是使用美国语言环境创建NSDateFormatter,而不考虑系统的语言环境,以确保“PM”将是“PM”:

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];
    

    然后,我将日期(年、月、日)转换为字符串:

    [formatter setDateFormat:@"yyyy-MM-dd"];
    NSString *date = [formatter stringFromDate:now];
    

    对于下一部分,我得到了小时、分钟和秒:

    [formatter setDateFormat:@"hh"];
    NSString *hours = [formatter stringFromDate:now];
    [formatter setDateFormat:@"mm"];
    NSString *minutes = [formatter stringFromDate:now];
    [formatter setDateFormat:@"ss"];
    NSString *seconds = [formatter stringFromDate:now];
    

    接下来,我得到了一天的一部分:

    [formatter setDateFormat:@"a"];
    NSString *partOfDay = [formatter stringFromDate:now];
    

    然后是逻辑:如果一天中的部分时间是下午但时间少于 12,我们只需要更正它。在代码中:

    if([partOfDay isEqualToString:@"PM"] && [hours intValue] < 12) {
        hours = [[NSString alloc] initWithFormat:@"%i", ([hours intValue] + 12)];
    }
    

    修改后,我们准备将字符串放在一起,以便将日期时间保存到 SQL 中:

    NSString *sqlDateTime = [[NSString alloc] initWithFormat:@"%@ %@:%@:%@", date, hours, minutes, seconds];
    

    仅此而已。从现在开始,我们只能希望 Apple 能够修复这个错误,使其能够正常工作。

    我希望这会有所帮助。

    【讨论】:

    • 如果语言环境与 en_US 不同,并且“PM”不是“PM”怎么办?
    • AM 和 PM 来自拉丁语 'ante meridiem' 和 'post meridiem' 短语,意思是中午之前/之后。除了英语,它们不用于任何其他语言。 (en.wikipedia.org/wiki/12-hour_clock) 我试图找到等价物,但没有成功,所以我假设你的场景——尽管它非常有效——永远不会发生。
    • 它发生了。 AM/PM 已本地化。我可以证明希伯来语等价物。
    • @LeoNatan,实际上,你是对的,很抱歉只触及表面...... :) 它发生了,但你仍然可以要求 NSDateFormatter 使用 en_US 格式和 [formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]] 和这样,无论实际系统的语言环境如何,您都可以确保“PM”将成为“PM”。
    • 我完全同意 Leo!但是,我的示例代码解释了我遇到的一个场景,我需要将 正确 时间以 24 小时格式 (@"yyyy-MM-dd hh:mm:ss") 存储在数据库中,以便以后进行比较,所有这些都不是为了显示实际数据,而是在后台进行计算。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多