2009-12-18 47 views
37

我以为我最近看到了一些回答这个问题的东西,但现在我找不到它了。这里是我现在使用的代码来确定设置是否用于24小时时间显示。它在美国适用于我,但我不知道它是否适用于所有地区。这是足够的还是有更好的方法来找出当前的设置?如何确定iPhone是否设置为12小时或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; 
} 

回答

77

下面是做到这一点的最好办法:

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

这将使用名为 “J” 一个特殊的日子模板字符串。根据ICU Spec, “J” ...

请求的区域设置(H,H,K,或k)的优选格式小时,如通过是否H,H,K,或k是用来确定用于语言环境的标准短时间格式。在实现这样的API时,在开始与availableFormats数据匹配之前,必须用h,H,K或k替换'j'。请注意,在传递给API的骨架中使用'j'是使骨架请求成为语言环境首选时间循环类型(12小时或24小时)的唯一方法。

最后一句话很重要。它“是获得骨架请求语言环境首选时间周期类型的唯一方式”。由于NSDateFormatterNSCalendar构建在ICU库上,因此这里也是如此。

+0

不错的3班轮。我想知道,“a”究竟代表什么?是否有可能一些神秘的设置可以将时间周期符号更改为“AM”?如果范围行改为' NSRange containsA = [formatStringForHours rangeOfString:@“a”options:NSCaseInsensitiveSearch];'? – Wienke

+3

@Wienke“a”是AM/PM代号的ICU符号。它永远不可能是“A”,因为ICU使用“A”表示完全不同的事物(当天的毫秒数)。 –

+0

+1,我觉得更舒服的搜索一个具有定义的固定含义的角色,并且不会根据语言环境而改变。 – DarkDust

21

我刚刚问了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 

希望这有助于!

+0

这个分类方法存在一个小问题。您应该在创建格式化程序之后添加一行'[formatter setLocale:self];否则仅**使用当前语言环境。 –

+0

哦,是的,好点! –

+0

没问题。顺便说一句,伟大的解决方案,我很高兴使用它。 –

6

我给戴夫的回答了一枪,但与德国的语言环境进行测试时 - 当使用24小时时间周期的区域 - 我意识到这将是更好的检查^hķ格式字符串,而不是a,并且引用的子串应该被忽略。

对于德语语言环境,我在iOS模拟器中请求模板“j”的日期格式以及设备上的“HH'Uhr'”时返回“HH a”。 (不明白为什么是有区别的。)

这里是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

感谢您分享这一点,它确实在德语语言环境中使用24小时制表示“HH'Uhr”。因此,有了这个,我们建议一种可能性,即某些语言可能会返回包含“a”的内容,即使在24小时格式中也是如此吗? –

0

在斯威夫特4:

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