8

我正在使用 UIDatePicker 来选择时间。我还在自定义选择器的背景,但是我需要 2 个不同的图像,具体取决于用户是使用 12 小时模式(显示 AM/PM 列)还是 24 小时模式。如何检测 12/24 小时时间的用户设置?

谢谢

4

3 回答 3

39

甚至比其他人更短:

NSString *format = [NSDateFormatter dateFormatFromTemplate:@"j" options:0 locale:[NSLocale currentLocale]];
BOOL is24Hour = ([format rangeOfString:@"a"].location == NSNotFound);

解释

表示 am/pm 符号的字符串格式化字符是“a”,如Unicode 区域设置标记语言 – 第 4 部分:日期中所述。

同一份文档还解释了特殊的模板符号“j”:

这是一个特殊用途的符号。它不得出现在模式或骨架数据中。相反,它保留用于传递给执行灵活日期模式生成的 API 的骨架中。在这种情况下,它会请求区域设置的首选小时格式(h、H、K 或 k),这取决于是否在区域设置的标准短时间格式中使用了 h、H、K 或 k。在此类 API 的实现中,在开始与 availableFormats 数据进行匹配之前,必须将“j”替换为 h、H、K 或 k。请注意,在传递给 API 的框架中使用“j”是让框架请求区域设置的首选时间周期类型(12 小时或 24 小时)的唯一方法。

NSString方法dateFormatFromTemplate:options:locale:在 Apple 的NSDateFormatter文档中有所描述:

返回一个本地化的日期格式字符串,表示为指定区域设置适当排列的给定日期格式组件。

因此,该方法的作用是将@"j"您作为模板传入的格式字符串转换为适合NSDateFormatter. 如果此字符串@"a"在任何地方都包含 am / pm 符号,那么您知道区域设置(以及操作系统为您询问的其他用户设置)希望显示 am / pm。

于 2012-09-02T14:23:17.307 回答
7

日期扩展形式的两个最流行的解决方案的 Swift (3.x) 版本:

extension Date {

    static var is24HoursFormat_1 : Bool  {
        let dateString = Date.localFormatter.string(from: Date())

        if dateString.contains(Date.localFormatter.amSymbol) || dateString.contains(Date.localFormatter.pmSymbol) {
            return false
        }

        return true
    }

    static var is24HoursFormat_2 : Bool {
        let format = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.autoupdatingCurrent)
        return !format!.contains("a")
    }

    private static let localFormatter : DateFormatter = {
        let formatter = DateFormatter()

        formatter.locale    = Locale.autoupdatingCurrent
        formatter.timeStyle = .short
        formatter.dateStyle = .none

        return formatter
    }()
}

用法 :

Date.is24HoursFormat_1
Date.is24HoursFormat_2

NSDate 扩展形式的两个最流行的解决方案的 Swift (2.0) 版本:

extension NSDate {

    class var is24HoursFormat_1 : Bool  {
        let dateString = NSDate.localFormatter.stringFromDate(NSDate())

        if dateString.containsString(NSDate.localFormatter.AMSymbol) || dateString.containsString(NSDate.localFormatter.PMSymbol) {
            return false
        }

        return true
    }

    class var is24HoursFormat_2 : Bool {
        let format = NSDateFormatter.dateFormatFromTemplate("j", options: 0, locale: NSLocale.autoupdatingCurrentLocale())
        return !format!.containsString("a")
    }

    private static let localFormatter : NSDateFormatter = {
        let formatter = NSDateFormatter()

        formatter.locale    = NSLocale.autoupdatingCurrentLocale()
        formatter.timeStyle = .ShortStyle
        formatter.dateStyle = .NoStyle

        return formatter
    }()
}

请注意,Apple 在 NSDateFormatter (日期格式化程序)上说以下内容:

创建日期格式化程序并不是一项廉价的操作。如果您可能经常使用格式化程序,则缓存单个实例通常比创建和处置多个实例更有效。一种方法是使用静态变量。

这就是静态让的原因

其次,您应该使用 NSLocale.autoupdatingCurrentLocale() (对于 is24HoursFormat_1 ),这样您将始终获得实际的当前状态。

于 2015-11-01T22:45:47.890 回答
3

可能还有很多很多...

于 2012-08-31T11:32:31.830 回答