Как я могу определить, настроен ли iPhone на 12-часовой или 24-часовой показ времени? - PullRequest
38 голосов
/ 18 декабря 2009

Я думал, что видел что-то, отвечающее на это недавно, но теперь я не могу найти это. Вот код, который я использую сейчас, чтобы определить, установлены ли настройки для отображения времени 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 ]

82 голосов
/ 26 июля 2012

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

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")

Swift 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, то же самое справедливо и здесь.

22 голосов
/ 29 декабря 2009

Я только что задал подобный вопрос здесь, и мне удалось найти достойный способ определения этого с помощью небольшой функции, которую я добавил в категорию 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

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

6 голосов
/ 11 мая 2014

Я дал ответ Дейву, но при тестировании с немецким языком - регионом, где используется 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
0 голосов
/ 14 октября 2017

В Swift 4:

let formatString: String = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.current)!
let hasAMPM = formatString.contains("a")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...