如何确定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; }
这是最好的方法来做到这一点:
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”的特殊date模板string。 根据ICU规范 ,“j”…
根据语言环境的标准短时间格式是使用h,H,K还是k来确定地区(h,H,K或k)的首选小时格式。 在实现这样的API时,在开始与availableFormats数据匹配之前,必须用h,H,K或kreplace“j”。 请注意,在传递给API的骨架中使用“j”是使骨架请求成为语言环境的首选时间循环types(12小时或24小时)的唯一方法。
最后一句话很重要。 它“是获得一个语言环境首选时间周期types的框架请求的唯一方法”。 由于NSDateFormatter
和NSCalendar
build立在ICU库上,所以在这里也是一样的。
我刚刚在这里问了一个类似的问题 ,我设法找出一个体面的方式来确定这个我已经添加到一个NSLocale
类别的一个小function。 这似乎是相当准确的,并没有发现任何问题,而与几个地区的testing。
@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
希望这可以帮助!
我给了Dave的答案一个镜头,但是当用德语localetesting – 一个使用24小时时间周期的地区 – 我意识到最好是检查格式string中的H或k而不是a ,并且引用的子string应该是忽略。
对于德语区域设置,当在iOS模拟器中请求模板“j”的date格式以及设备上的“HH'Uhr'”时,我会返回“HH a”。 (不明白为什么有所不同。)
这里是我用来检查24小时时间周期的NSLocale
类别:
@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")