2009-12-18 60 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") 
相關問題