Как определить, установлен ли 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;
}
Ответы
Ответ 1
Вот лучший способ сделать это:
NSString *formatStringForHours = [NSDateFormatter dateFormatFromTemplate:@"j" options:0 locale:[NSLocale currentLocale]];
NSRange containsA = [formatStringForHours rangeOfString:@"a"];
BOOL hasAMPM = containsA.location != NSNotFound;
в Swift:
let formatString: NSString = NSDateFormatter.dateFormatFromTemplate("j", options: 0, locale: NSLocale.currentLocale())!
let hasAMPM = formatString.containsString("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, это также верно.
Ответ 2
Я просто спросил аналогичный вопрос здесь, и мне удалось найти достойный способ определить это с помощью небольшой функции, которую я добавил в категория 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
Надеюсь, это поможет!
Ответ 3
Я дал Дэйву ответ на выстрел, но при тестировании с немецким языком - регионом, где используется 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
Ответ 4
В Swift 4:
let formatString: String = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.current)!
let hasAMPM = formatString.contains("a")