【问题标题】:Detect if time format is in 12hr or 24hr format检测时间格式是 12 小时还是 24 小时格式
【发布时间】:2011-11-18 21:17:24
【问题描述】:

有什么方法可以检测应用程序的当前设备是否使用 12h 我们的 24h 格式,以便我可以根据用户的语言/位置设置使用一个 NSDateFormatter 12h 和一个 24h?就像 UIDatePicker 检测并显示 AM/PM 选择器(如果它是 12h 格式)。

【问题讨论】:

  • @progrmr 绝对是确定是否设置 24 小时制时钟的好解决方案,但这取决于日期格式化程序的行为。 OP 希望此信息使用日期格式化程序格式化字符串,以便解决方案涉及添加类类别、创建日期格式化程序、将日期转换为字符串、在字符串中搜索两次 AM/PM 符号,然后将代码分支到使用 12 小时或 24 小时格式,因为它已经为您这样做了。
  • @Joe 我知道,但有时您出于其他原因需要知道,例如将“AM”放在具有不同字体的单独 UILabel 中,OP 并不清楚他想要的确切原因知道。

标签: objective-c ios cocoa-touch nstimezone


【解决方案1】:

我想通了,这很容易。我刚刚将此代码添加到viewDidLoad:

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setLocale:[NSLocale currentLocale]];
[formatter setDateStyle:NSDateFormatterNoStyle];
[formatter setTimeStyle:NSDateFormatterShortStyle];
NSString *dateString = [formatter stringFromDate:[NSDate date]];
NSRange amRange = [dateString rangeOfString:[formatter AMSymbol]];
NSRange pmRange = [dateString rangeOfString:[formatter PMSymbol]];
BOOL is24h = (amRange.location == NSNotFound && pmRange.location == NSNotFound);
[formatter release];
NSLog(@"%@\n",(is24h ? @"YES" : @"NO"));

根据语言环境,它可以完美地返回YES 或NO。

【讨论】:

  • 这仅在本地日历使用与手机相同的格式时有效,但在 iOS 上,您可以专门设置时间格式,使其与本地日历中使用的格式不同。
【解决方案2】:

这是一个 Swift 3.0 更新版本

func using12hClockFormat() -> Bool {

    let formatter = DateFormatter()
    formatter.locale = Locale.current
    formatter.dateStyle = .none
    formatter.timeStyle = .short

    let dateString = formatter.string(from: Date())
    let amRange = dateString.range(of: formatter.amSymbol)
    let pmRange = dateString.range(of: formatter.pmSymbol)

    return !(pmRange == nil && amRange == nil)
}

【讨论】:

    【解决方案3】:

    这是对我有用的快速解决方案,上面的两个没有。

    let dateString: String = DateFormatter.dateFormat(
        fromTemplate: "j", options: 0,
        locale: Locale.current
    )!
    if(dateString.contains("a")){
    // 12 h format
       return true
    }else{
    // 24 h format
       return false
    }
    

    【讨论】:

    • “j”代表什么?
    【解决方案4】:

    对于 Swift 5.3。 在 Xcode 12 上测试。

    func is12hClockFormat() -> Bool {
        let formatString = DateFormatter.dateFormat(
            fromTemplate: "j",
            options: 0,
            locale: Locale.current
        )!
        return formatString.contains("a")
    }
    

    这使用称为“j”的特殊日期模板字符串。根据 ICU 规范,“j”...

    请求区域设置的首选小时格式(h、H、K 或 k),由是否在区域设置的标准短时间格式中使用 h、H、K 或 k 来确定。在此类 API 的实现中,在开始与 availableFormats 数据进行匹配之前,必须将“j”替换为 h、H、K 或 k。请注意,在传递给 API 的框架中使用“j”是让框架请求区域设置的首选时间周期类型(12 小时或 24 小时)的唯一方法。

    最后一句话很重要。它“是让骨架请求语言环境的首选时间周期类型的唯一方法”。由于 NSDateFormatter 和 NSCalendar 是建立在 ICU 库上的,所以这里也是如此。

    收集自https://stackoverflow.com/a/11660380/3428146

    【讨论】:

      【解决方案5】:

      这里是 Swift 版本:

      func using12hClockFormat() -> Bool {
      
          let formatter = NSDateFormatter()
          formatter.locale = NSLocale.currentLocale()
          formatter.dateStyle = NSDateFormatterStyle.NoStyle
          formatter.timeStyle = NSDateFormatterStyle.ShortStyle
      
          let dateString = formatter.stringFromDate(NSDate())
          let amRange = dateString.rangeOfString(formatter.AMSymbol)
          let pmRange = dateString.rangeOfString(formatter.PMSymbol)
      
          return !(pmRange == nil && amRange == nil)
      }
      

      【讨论】:

      • 您将三元运算符用作 NOT,这只会使其更难阅读。返回行应该是这个return !(pmRange == nil && amRange == nil)
      • return pmRange != nil || amRange != nil 会不会更容易(更具可读性)?
      【解决方案6】:

      Objective C 类NSDate+Extensions:

      @import Foundation;
      
      @interface NSDate (Extensions)
      
      - (NSString *)getTimeString;
      
      @end
      
      
      #import "NSDate+Extensions.h"
      
      @implementation NSDate (Extensions)
      
      - (NSString *)getTimeString
      {
          NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
          if ([self isTwelveHourDateFormat]) {
              [formatter setDateFormat:@"hh:mm\ndd MMM"];
          }
          else {
              [formatter setDateFormat:@"HH:mm\ndd MMM"];
          }
          return [formatter stringFromDate:self];
      }
      
      - (BOOL)isTwelveHourDateFormat
      {
          NSString *dateFormat = [NSDateFormatter dateFormatFromTemplate:@"j" options:0 locale:[NSLocale currentLocale]];
          return [dateFormat containsString:@"a"];
      }
      
      @end
      

      【讨论】:

      • “j”代表什么?
      猜你喜欢
      • 2021-05-09
      • 1970-01-01
      • 2018-02-19
      • 2012-07-08
      • 1970-01-01
      • 2011-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多