Detect if time format is in 12hr or 24hr format
Is there any way to detect if the current device of the app uses 12h our 24h format, so that I can use one NSDateFormatter for 1开发者_运维问答2h and one for 24h depending on the users language/loaction setting? Just Like the UIDatePicker detects and shows the AM/PM picker if it is 12h format.
I figured it out, its pretty easy. I just added this code to 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"));
And it perfectly returns YES
or NO
depending on the locale.
And here is a Swift 3.0 updated version
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)
}
this is swift solution that worked for me, those two above did not.
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
}
For Swift 5.3. Tested on Xcode 12.
func is12hClockFormat() -> Bool {
let formatString = DateFormatter.dateFormat(
fromTemplate: "j",
options: 0,
locale: Locale.current
)!
return formatString.contains("a")
}
This uses a special date template string called "j". According to the ICU Spec, "j"...
requests the preferred hour format for the locale (h, H, K, or k), as determined by whether h, H, K, or k is used in the standard short time format for the locale. In the implementation of such an API, 'j' must be replaced by h, H, K, or k before beginning a match against availableFormats data. Note that use of 'j' in a skeleton passed to an API is the only way to have a skeleton request a locale's preferred time cycle type (12-hour or 24-hour).
That last sentence is important. It "is the only way to have a skeleton request a locale's preferred time cycle type". Since NSDateFormatter and NSCalendar are built on the ICU library, the same holds true here.
Collected from https://stackoverflow.com/a/11660380/3428146
Here is the Swift version:
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)
}
Objective C category 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
精彩评论