【问题标题】:NSDateFormatter with 24 hour times具有 24 小时时间的 NSDateFormatter
【发布时间】:2010-01-25 20:12:22
【问题描述】:

我有一个倒计时计时器,可以从当前日期/时间倒计时到特定的未来日期/时间。除了一个问题外,它工作得很好。我使用NSDateFormatterdateFromString 输入未来日期。尽管表明它不支持 24 小时制,但它似乎无法接受超过 12 的任何时间(小时)。有没有办法启用 24 小时时钟支持或解决方法?这是我的一些代码:

NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"yyyy-MM-dd hh:mm:ss"];
NSDate *myDate = [df dateFromString:@"2010-03-14 15:00:00"];

【问题讨论】:

  • 本地化怎么样...?您不应该先正确本地化NSDateFormatter 吗?

标签: objective-c iphone nsdateformatter


【解决方案1】:

NSDateFormatter 遵循Unicode standard for date and time patterns。使用 'H' 表示 24 小时制的小时:

NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *myDate = [df dateFromString:@"2010-03-14 15:00:00"];

【讨论】:

  • 令人惊讶不是吗?我刚刚发现我自己的一个应用程序失败了,因为尽管在格式字符串中使用了 HH,但用户设置会覆盖它。疯了!
  • 这个答案具有误导性。我同意 Mavrick3 和 Roger 的观点。用户设置覆盖标准时间模式的 HH。日期格式化程序文档令人讨厌地暗示了这种行为:在所有情况下,您应该考虑格式化程序默认使用用户的区域设置 (currentLocale) 与用户的偏好设置叠加。
  • 如果原始问题中提到的日期格式是 24 小时并且用户的区域设置为 12 小时,我们该怎么办?在那种情况下 [[NSDate date] timeIntervalSinceDate:@"my 24 hour datetime"] 返回 "nan"...非常烦人!谁能告诉我如何让这个工作。基本上,无论用户的区域设置如何,我都需要始终使用 24 小时时钟来计算 timeIntervalSinceDate。我不知道该怎么做。
  • NSDateFormatter 行为在Technical Q&A QA1480 中进行了解释。
  • 要覆盖用户的设置,直接设置日期格式化程序的区域设置:df.locale = ...
【解决方案2】:

我遇到了同样的问题,并且使用 HH 仅在某些设备上有效,例如 Roger 也已验证。最后,这是对我有用的解决方案,我希望它对其他人有用。找到这个答案很困难,没有论坛,它实际上是按照苹果文档的反复试验。

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];

    [dateFormatter setLocale:enUSPOSIXLocale];

    NSString *dateFormat = @"dd/MM/yyyy HH:mm"; //MM for month, mm for minutes

    [dateFormatter setDateFormat:dateFormat];
    [dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
    date = [dateFormatter dateFromString:string];

【讨论】:

【解决方案3】:

我在 Swift 上的解决方案:

let formatter = NSDateFormatter()
var defIdentifer = formatter.locale.localeIdentifier
if !defIdentifer.hasSuffix("_POSIX") {
    defIdentifer = defIdentifer+"_POSIX"
    let locale = NSLocale(localeIdentifier: defIdentifer)
    formatter.locale = locale
}
formatter.dateFormat = "HH:mm"

【讨论】:

  • 很好的答案!这就是我想要的。
【解决方案4】:

我最近遇到了类似的问题,我的应用中没有HHNSDateFormatter 忽略hha(AM/PM 符号)和G(循环时代名称)。

我惊讶地发现,如果我去我的设备的本地化设置并做出一些随机选择,所有的怪胎都消失了,错误不会再次产生。很奇怪。

然后我在模拟器上进行了测试以对其进行一些研究。有我的解决方案:

创建NSDateFormatter 后,即使您使用当前语言环境,也要显式设置语言环境属性,更重要的是,不要使用[NSLocale currentLocale],这是错误的,可能会被用户设置以某种方式“覆盖”,请使用systemLocale 或使用语言环境标识符显式创建 NSLocale 实例。

【讨论】:

    【解决方案5】:

    取自 NSDateFormatters 上的Apple Technical Q&A

    问:我正在使用 NSDateFormatter 来解析 Internet 样式的日期,但是对于某些地区的某些用户来说这会失败。我已经设置了一个特定的日期格式字符串;这不应该强制 NSDateFormatter 独立于用户的区域设置工作吗?

    答:不可以。虽然设置日期格式字符串似乎适用于大多数用户,但这不是解决此问题的正确方法。在很多地方,格式字符串的行为都出乎意料。

    这就是我在 Swift 中的做法:

    private let dateFormatter: NSDateFormatter = {
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
        dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
        dateFormatter.timeZone = NSTimeZone.init(forSecondsFromGMT: 0)
        return dateFormatter
    }()
    

    【讨论】:

      【解决方案6】:

      当用户在 iPhone 上设置 12 小时格式而不更改语言环境和设置时区时,从 24 小时字符串获取 NSDate 的 Objective C 版本:

      NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
      NSString *localeId = dateFormatter.locale.localeIdentifier;
      if (! [localeId hasSuffix:@"_POSIX"]) {
          localeId = [localeId stringByAppendingString:@"_POSIX"];
          dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:localeId];
      }
      dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH.mm.ss";
      
      NSDate *date  = [dateFormatter dateFromString:dateText];
      

      【讨论】:

      • 这就是我要找的。​​span>
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-21
      • 1970-01-01
      • 2015-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-12
      相关资源
      最近更新 更多