Swift NSDateFormatter在OS X和iOS中检测24小时时钟

Swift NSDateFormatter在OS X和iOS中检测24小时时钟,swift,nsdate,nsdateformatter,Swift,Nsdate,Nsdateformatter,我想检查用户在OS X和iOS中是否选择了12小时或24小时时钟作为首选时钟。因此,我想检测用户是否执行了以下操作: 在Mac上,系统首选项为日期和时间,使用24小时时钟 在iPhone上,首选项是设置、常规、日期和时间、24小时时间 我目前有以下代码,但它总是返回12小时时钟表示的时间,即使用户设置的系统首选项是24小时时钟 let timeFormatter = NSDateFormatter() timeFormatter.locale = NSLocale.currentLocale

我想检查用户在OS X和iOS中是否选择了12小时或24小时时钟作为首选时钟。因此,我想检测用户是否执行了以下操作:

  • 在Mac上,系统首选项为日期和时间,使用24小时时钟
  • 在iPhone上,首选项是设置、常规、日期和时间、24小时时间
我目前有以下代码,但它总是返回12小时时钟表示的时间,即使用户设置的系统首选项是24小时时钟

let timeFormatter = NSDateFormatter()
timeFormatter.locale = NSLocale.currentLocale()
timeFormatter.dateStyle = NSDateFormatterStyle.NoStyle
timeFormatter.timeStyle = NSDateFormatterStyle.ShortStyle

let ampmtext = timeFormatter.stringFromDate(NSDate())
println(ampmtext)

if ampmtext.rangeOfString("M") != nil {
    println("12-hour clock")
} else {
    println("24-hour clock")
}

我想为Mac和iPhone找到一个用Objective-C和Swift编写的解决方案,可以检测设备时钟是显示24小时还是12小时。

日期模板功能有一个巧妙的技巧。有一个模板说明符
j
,该说明符将转换为小时格式,具体取决于区域设置是使用12小时格式还是24小时格式。它将变成类似于12小时格式的
ha
(本例中为en_-US)或24小时格式的
HH
(en_-GB)

然后,您只需检查日期格式是否包含
a

//let locale = NSLocale(localeIdentifier: "de_DE")
//let locale = NSLocale(localeIdentifier: "en_US")
//let locale = NSLocale(localeIdentifier: "en_GB")
let locale = NSLocale.currentLocale()

let dateFormat = NSDateFormatter.dateFormatFromTemplate("j", options: 0, locale: locale)!

if dateFormat.rangeOfString("a") != nil {
    println("12 hour")
}
else {
    println("24 hour")
}
这也应该考虑到格式覆盖


这与您的检查类似,但您不应尝试检查
AM
PM
。这些是英文版本,还有很多。例如,在德国,如果强制使用12小时格式,iOS将使用
nachm.
vorm.
。正确的方法是检查
a
的格式

Mac OS X菜单栏中使用的日期格式包含在文件
~/Library/Preferences/com.apple.menuextra.clock.plist
中。在我的系统(en_US locale)上,在非24小时的时间内看起来是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>DateFormat</key>
    <string>EEE h:mm a</string>
    <key>FlashDateSeparators</key>
    <false/>
    <key>IsAnalog</key>
    <false/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>DateFormat</key>
    <string>EEE H:mm</string>
    <key>FlashDateSeparators</key>
    <false/>
    <key>IsAnalog</key>
    <false/>
</dict>
</plist>

日期格式
嗯
闪蒸分离器
伊萨纳洛格
24小时都是这样:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>DateFormat</key>
    <string>EEE h:mm a</string>
    <key>FlashDateSeparators</key>
    <false/>
    <key>IsAnalog</key>
    <false/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>DateFormat</key>
    <string>EEE H:mm</string>
    <key>FlashDateSeparators</key>
    <false/>
    <key>IsAnalog</key>
    <false/>
</dict>
</plist>

日期格式
嗯
闪蒸分离器
伊萨纳洛格

您可以使用命令行中的
defaults read com.apple.menuextra.clock DateFormat
或Obj-C或Swift中的
NSUserDefaults
检索格式字符串。然后可以检查格式字符串是否包含
a
。如果是,则时钟不会设置为24小时。

Swift 4

以下是对公认答案的快速解释:

func is24Hour() -> Bool {
    let dateFormat = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.current)!

    return dateFormat.firstIndex(of: "a") == nil
}
用法:

if is24Hour() {
    // should show 24 hour time
} else {
    // should show 12 hour time
}

看见这和你的问题正好相反,但它给了你一些背景知识。(尽管我不知道有什么可靠的方法可以明确地测试12/24设置,尽管有所有可能的区域设置,等等。)@HotLicks我编辑了我的问题。代码可以工作,但错误在于我如何处理Mac上的设置以及如何使用iPhone模拟器进行iOS操作。当我看到这个问题时,我想不出在iPhone模拟器上引发它的方法——我们必须用真实的手机进行测试。(并不担心OSx)我同意,这似乎是一个更好的方法。最后一件事——有没有办法在iPhone模拟器中测试这一点?看起来您必须在实际设备上运行代码,但是在模拟器中将区域设置更改为24小时时钟会很方便。据我所知,iOS模拟器不支持这些自定义格式。谢谢,这在swift 5.1中仍然可以完美地工作,Xcode 11.2 Beta 2