Как определить, настроен ли iPhone на 12-часовой или 24-часовой дисплей?

Я думал, что видел что-то, отвечающее на это недавно, но теперь я не могу найти это. Вот код, который я использую сейчас, чтобы определить, установлены ли настройки для отображения времени 24 часа. Это работает для меня в США, но я не знаю, будет ли это работать во всех регионах. Это достаточно или есть лучший способ узнать текущие настройки для этого?

+(BOOL) use24HourClock
{
    BOOL using24HourClock = NO;

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];    
    [dateFormatter setLocale: [NSLocale currentLocale]];    
    [dateFormatter setDateStyle:kCFDateFormatterNoStyle];
    [dateFormatter setTimeStyle:kCFDateFormatterShortStyle];    
    // get date/time (1Jan2001 0000UTC)
    NSDate* midnight = [[NSDate alloc] initWithTimeIntervalSinceReferenceDate:0];   
    NSString* dateString = [dateFormatter stringFromDate: midnight];
    // dateString will either be "15:00" or "16:00" (depending on DST) or
    // it will be "4:00 PM" or "3:00 PM" (depending on DST)
    using24HourClock = ([dateString length] == 5);
    [midnight release];
    [dateFormatter release];    

    return using24HourClock;
}

4 ответа

Решение

Вот лучший способ сделать это:

NSString *formatStringForHours = [NSDateFormatter dateFormatFromTemplate:@"j" options:0 locale:[NSLocale currentLocale]];

NSRange containsA = [formatStringForHours rangeOfString:@"a"];
BOOL hasAMPM = containsA.location != NSNotFound;

в Свифте:

let formatString: NSString = NSDateFormatter.dateFormatFromTemplate("j", options: 0, locale: NSLocale.currentLocale())!
let hasAMPM = formatString.containsString("a")

Свифт 4:

let formatString = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.current)!
let hasAMPM = formatString.contains("a")

При этом используется специальная строка шаблона даты, которая называется "j". Согласно спецификации ICU, "j"...

запрашивает предпочтительный часовой формат для языкового стандарта (h, H, K или k), который определяется тем, используется ли h, H, K или k в стандартном коротком временном формате для языкового стандарта. В реализации такого API "j" должен быть заменен на h, H, K или k перед началом сопоставления с данными доступных форматов. Обратите внимание, что использование j в скелете, передаваемом в API, является единственным способом заставить скелет запрашивать предпочтительный тип временного цикла локали (12-часовой или 24-часовой).

Последнее предложение важно. Это "единственный способ заставить скелет запросить предпочтительный тип временного цикла локали". поскольку NSDateFormatter а также NSCalendar построены на библиотеке ICU, то же самое верно и здесь.

Я только что задал подобный вопрос здесь, и мне удалось найти достойный способ определения этого с помощью небольшой функции, которую я добавил в категорию NSLocale, Похоже, что он довольно точный и не обнаружил никаких проблем при тестировании в нескольких регионах.

@implementation NSLocale (Misc)
- (BOOL)timeIs24HourFormat {
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setLocale:self];
    [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 is24Hour = (amRange.location == NSNotFound && pmRange.location == NSNotFound);
    [formatter release];
    return is24Hour;
}
@end

Надеюсь это поможет!

Я дал ответ Дейва, но при тестировании с немецким языком - регионом, где используется 24-часовой цикл времени - я понял, что было бы лучше проверить H или k в строке формата вместо a, и что подстроки в кавычках должны быть игнорируются.

Для немецкой локали я получаю обратно "HH a" при запросе формата даты для шаблона "j" в симуляторе iOS и "HH 'Uhr'" на устройстве. (Не понимаю, почему вообще есть разница.)

Вот категория для NSLocale что я использую, чтобы проверить на 24-часовой цикл времени:

@interface NSLocale (TwentyFourHourTimeCycleCheck)

- (BOOL)uses24HourTimeCycle;

@end

@implementation NSLocale (TwentyFourHourTimeCycleCheck)

- (BOOL)uses24HourTimeCycle
{
    BOOL uses24HourTimeCycle = NO;

    NSString *formatStringForHours = [NSDateFormatter dateFormatFromTemplate:@"j" options:0 locale:self];
    NSScanner *symbolScanner = [NSScanner scannerWithString:formatStringForHours];

    NSString *singleQuoteCharacterString = @"'";

    // look for single quote characters, ignore those and the enclosed strings
    while ( ![symbolScanner isAtEnd] ) {

        NSString *scannedString = @"";
        [symbolScanner scanUpToString:singleQuoteCharacterString intoString:&scannedString];

        // if 'H' or 'k' is found the locale uses 24 hour time cycle, and we can stop scanning
        if ( [scannedString rangeOfString:@"H"].location != NSNotFound ||
             [scannedString rangeOfString:@"k"].location != NSNotFound ) {

            uses24HourTimeCycle = YES;

            break;
        }

        // skip the single quote
        [symbolScanner scanString:singleQuoteCharacterString intoString:NULL];
        // skip everything up to and including the next single quote
        [symbolScanner scanUpToString:singleQuoteCharacterString intoString:NULL];
        [symbolScanner scanString:singleQuoteCharacterString intoString:NULL];
    }

    return uses24HourTimeCycle;
}

@end

В Swift 4:

let formatString: String = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.current)!
let hasAMPM = formatString.contains("a")

В моем случае я просто устанавливаю timeStyle = .short для dateFormatter. (Свифт)

let yourCustomDate = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "hh:mm a"
dateFormatter.amSymbol = "am"
dateFormatter.pmSymbol = "pm"
dateFormatter.timeStyle = .short
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
let dateString = dateFormatter.string(from: yourCustomDate)

В результате dateString будет автоматически преобразован в 12 или 24 формат времени. Например: 18:30 в 12-часовом формате и 18:30 в 24-часовом формате.

Другие вопросы по тегам