سؤال

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 12h 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
}

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

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top