我以为我最近在SO上看到了回答这个问题,但现在我找不到了。这是我现在使用的代码,用于确定设置是否为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;
}
答案 0 :(得分:81)
这是最好的方法:
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")
斯威夫特4:
let formatString = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.current)!
let hasAMPM = formatString.contains("a")
这使用名为“j”的特殊日期模板字符串。根据{{3}},“j”......
请求区域设置(h,H,K或k)的首选小时格式,由h,H,K或k是否以区域设置的标准短时间格式使用来确定。在这种API的实现中,在开始与availableFormats数据匹配之前,'j'必须被h,H,K或k替换。请注意,在传递给API的骨架中使用'j'是让骨架请求区域设置的首选时间周期类型(12小时或24小时)的唯一方法。
最后一句很重要。它“是骨架请求区域设置的首选时间周期类型的唯一方法”。由于NSDateFormatter
和NSCalendar
是建立在ICU库上的,因此这里也是如此。
答案 1 :(得分:22)
我刚刚在这里问了一个similar question,我已经设法找到了一个很好的方法,通过我添加到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
希望这有帮助!
答案 2 :(得分:6)
我给了Dave的回答,但是在使用德国语言环境(使用24小时时间周期的区域)进行测试时,我意识到最好检查 H 或<格式字符串中的strong> k 而不是 a ,并且应该忽略引用的子字符串。
对于德国语言,我会回来&#34; HH a&#34;在请求模板&#34; j&#34;的日期格式时在iOS模拟器中,&#34; HH&#39; Uhr&#39;&#34;在设备上。 (不明白为什么会有差异。)
以下是我用来检查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
答案 3 :(得分:0)
在Swift 4中:
let formatString: String = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.current)!
let hasAMPM = formatString.contains("a")
答案 4 :(得分:0)
我这种情况下,我只是为dateFormatter设置了timeStyle = .short。 (迅速)
private void MediaEL_MediaOpened(object sender, RoutedEventArgs e)
{
IsOpened1 = true;
btnPlay_Click(btnPlay, EventArgs.Empty);
}
private void MediaEL2_MediaOpened(object sender, RoutedEventArgs e)
{
IsOpened2 = true;
btnPlay_Click(btnPlay, EventArgs.Empty);
}
因此, dateString 将自动转换为12或24时间格式。例如:12小时格式的下午6:30和24小时格式的18:30。