I would like to check if the user has selected the 12-hour or 24-hour clock as their preference in OS X and iOS. So I would like to detect if the user has done the following:
I currently have the following code but it always returns the time as represented by the 12-hour clock, even if the system preference set by the user is for the 24-hour clock.
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")
}
I would like to find a solution written in Objective-C and Swift for both the Mac and iPhone that can detect if the device clock displays 24-hour or 12-hour time.
Start Control Panel, and then under Clock, Language, and Region, click Change date, time or number formats. On the Formats tab, under Date and time formats, do one of the following: To change to 24-hour format, on the Short time drop-down list, select HH:mm and on the Long time drop-down list, select HH:mm:ss.
Instances of NSDateFormatter create string representations of NSDate objects, and convert textual representations of dates and times into NSDate objects. For user-visible representations of dates and times, NSDateFormatter provides a variety of localized presets and configuration options.
When you present information to the user, you should typically simply use the NSDateFormatter style constants to specify pre-defined sets of attributes that determine how a formatted date is displayed. If you need to generate a representation of a date in a precise format, however, you should use a format string.
To represent a quantity of time specified by an NSDateComponents object, use NSDateComponentsFormatter instead. When displaying a date to a user, you set the dateStyle and timeStyle properties of the date formatter according to your particular needs.
In macOS 10.12 and later or iOS 10 and later, use the NSISO8601DateFormatter class when working with ISO 8601 date representations. When working with fixed format dates, such as RFC 3339, you set the dateFormat property to specify a format string.
The date template function has a neat trick. There is a template specifier j
which will turn into an hour format depending if the locale uses 12 or 24 hour format. It'll turn into something like h a
for 12 hour (en_US in this case) or HH
for 24 hour format (en_GB).
Then you just have to check if the date format contains 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")
}
This should take format overwrites into account as well.
This is similar to your check, but you should not try to check for AM
or PM
. These are the english versions, there are many more. For example in Germany if you force a 12 hour format iOS uses nachm.
and vorm.
. The correct way is to check the format for a
.
Swift 4
Here's a swift 4 interpretation of the accepted answer:
func is24Hour() -> Bool {
let dateFormat = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.current)!
return dateFormat.firstIndex(of: "a") == nil
}
Usage:
if is24Hour() {
// should show 24 hour time
} else {
// should show 12 hour time
}
Use this extension
extension Locale {
static var is24Hour: Bool {
let dateFormat = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.current)!
return dateFormat.firstIndex(of: "a") == nil
}
}
Free to use anywhere
if Locale.is24Hour {
// Show 24 hour time
} else {
// Show 12 hour time
}
The date format used in the menu bar on Mac OS X is contained in the file ~/Library/Preferences/com.apple.menuextra.clock.plist
. On my system (en_US locale) it looks like this for non-24 hour time:
<?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>
and like this for 24-hour time:
<?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>
You can retrieve the format string using defaults read com.apple.menuextra.clock DateFormat
from the command line or NSUserDefaults
from Obj-C or Swift. You can then check if the format string contains a
. If it does the clock is not set to 24-hour time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With