App的國(guó)際化和本地化(五) —— 使用區(qū)域設(shè)置格式化數(shù)據(jù)(一)

版本記錄

版本號(hào) 時(shí)間
V1.0 2018.05.10

前言

很多APP都有國(guó)際化版本,常見(jiàn)于一些大公司的產(chǎn)品,比如Facebook、Wechat等,那么國(guó)際化需要我們APP做哪些更改呢,接下來(lái)這幾篇就一起來(lái)看一下APP的國(guó)際化和本地化。感興趣的可以看上面幾篇。
1. App的國(guó)際化和本地化(一) —— 簡(jiǎn)單介紹(一)
2. App的國(guó)際化和本地化(二) —— 查看語(yǔ)言和區(qū)域設(shè)置(一)
3. App的國(guó)際化和本地化(三) —— 國(guó)際化用戶界面(一)
4. App的國(guó)際化和本地化(四) —— 國(guó)際化代碼(一)

回顧

上一篇主要介紹國(guó)際化代碼,本篇主要介紹使用區(qū)域設(shè)置格式化數(shù)據(jù)。


Formatting Data Using the Locale Settings - 使用區(qū)域設(shè)置格式化數(shù)據(jù)

不同的國(guó)家和地區(qū)對(duì)于數(shù)字和時(shí)間信息的格式有不同的約定。 區(qū)域設(shè)置提供有關(guān)當(dāng)前用戶使用的格式的信息,在編寫處理面向用戶的數(shù)據(jù)類型的代碼時(shí)必須考慮這些信息。 用戶通過(guò)在iOS設(shè)備的設(shè)置和Mac上的系統(tǒng)首選項(xiàng)中選擇區(qū)域來(lái)設(shè)置區(qū)域設(shè)置。 用戶還可以在應(yīng)用程序運(yùn)行時(shí)更改區(qū)域設(shè)置。 因此,如果您在代碼中操作數(shù)據(jù)對(duì)象并將其呈現(xiàn)給用戶,請(qǐng)使用locale APIs正確格式化數(shù)據(jù)。

您不需要知道如何格式化所有不同地區(qū)中的數(shù)據(jù)。 您可以使用自動(dòng)生成區(qū)域敏感格式的預(yù)設(shè)樣式。 只要您在將它們呈現(xiàn)給用戶之前將其轉(zhuǎn)換為區(qū)域性敏感格式,就可以使用自定義格式。 本章介紹如何編寫區(qū)域敏感代碼。


About Locale Formats - 關(guān)于區(qū)域格式

區(qū)域設(shè)置表示特定用戶的格式選擇,而不是用戶的首選語(yǔ)言。 這些通常是相同的,但可以不同。 例如,住在德國(guó)的講英語(yǔ)的母語(yǔ)人士可能會(huì)選擇英語(yǔ)作為語(yǔ)言,德國(guó)作為該地區(qū)。 文本以英文顯示,但日期,時(shí)間和數(shù)字遵循德國(guó)格式規(guī)則。 日在月的前面和24小時(shí)的時(shí)間表示,如Table 4-1所示。

Table 4-1 Data formats in United States and Germany

在Mac上,您可以在系統(tǒng)偏好設(shè)置中預(yù)覽修改的區(qū)域設(shè)置首選項(xiàng)。 從“地區(qū)”彈出式菜單中選擇地理區(qū)域時(shí),會(huì)顯示日期,時(shí)間和數(shù)字格式的樣本。 該屏幕截圖顯示了當(dāng)英語(yǔ)是該語(yǔ)言并且日本是該地區(qū)時(shí)的示例數(shù)據(jù)格式:

Mac用戶還可以通過(guò)單擊Advanced按鈕來(lái)自定義日期,時(shí)間和數(shù)字格式,如Reviewing Language and Region Preferences on Your Mac中所述。


Using the Locale Object - 使用地區(qū)對(duì)象

NSLocale對(duì)象封裝有關(guān)特定區(qū)域的格式標(biāo)準(zhǔn)的信息。 在格式化面向用戶的文本時(shí),會(huì)傳遞一個(gè)代表用戶所選區(qū)域的NSLocale對(duì)象。 NSLocale類提供用于獲取用戶的區(qū)域?qū)ο蟮念惙椒ㄒ约坝嘘P(guān)支持的區(qū)域的其他信息。

1. Getting the User’s Locale - 獲取用戶區(qū)域

您可以使用NSLocale類中的currentLocaleautoupdatingCurrentLocale類方法來(lái)獲取用戶的區(qū)域。

如果使用currentLocale方法,則保證返回對(duì)象的屬性值不會(huì)更改。 因此,如果要執(zhí)行需要一致的操作,請(qǐng)使用currentLocale方法。

如果使用autoupdatingCurrentLocale方法,那么當(dāng)用戶更改區(qū)域設(shè)置時(shí),屬性值可能會(huì)更改。 但是,如果返回的對(duì)象發(fā)生更改,則不會(huì)通知您。

要觀察區(qū)域設(shè)置首選項(xiàng)更改,請(qǐng)閱讀Registering for Locale and Time Zone Changes。

提示:系統(tǒng)設(shè)置與用戶設(shè)置不同。 不要使用systemLocale類方法來(lái)獲取用戶的區(qū)域。

2. Getting Information About a Locale - 獲取關(guān)于區(qū)域的信息

使用NSLocale類中的objectForKey:方法來(lái)訪問(wèn)有關(guān)語(yǔ)言環(huán)境的信息。 例如,將NSLocaleUsesMetricSystem密鑰傳遞給此方法以獲取布爾數(shù),該數(shù)字確定區(qū)域設(shè)置是否使用metric系統(tǒng)。

NSNumber *metricSystem = [[NSLocale currentLocale] objectForKey:NSLocaleUsesMetricSystem];

傳遞key為NSLocaleCurrencySymbol以獲取代表當(dāng)?shù)胤?hào)的字符串。

NSString *currencySymbol = [[NSLocale currentLocale] objectForKey:NSLocaleCurrencySymbol];

對(duì)于區(qū)域keys的完整列表,請(qǐng)參考NSLocale Component Keys

3. Getting Localized Language and Dialect Names - 獲取本地語(yǔ)言和方言名稱

不應(yīng)向用戶顯示API和文件夾名稱中指定語(yǔ)言和方言的標(biāo)識(shí)符,例如de-CHen-AUpt-PT。 要獲得可讀的本地化語(yǔ)言或方言名稱,請(qǐng)?jiān)贜SLocale類中使用displayNameForKey:value:方法,傳遞NSLocaleIdentifier作為關(guān)鍵參數(shù)。

To get the localized name for languages and dialects - 獲取地區(qū)名稱用于語(yǔ)言和方言

  • 獲取APP正在使用的語(yǔ)言
NSString *languageID = [[NSBundle mainBundle] preferredLocalizations].firstObject;

返回的字符串是標(biāo)識(shí)書(shū)面語(yǔ)言或方言的language ID,如Language and Locale IDs中所述。

  • 獲取關(guān)聯(lián)的地區(qū)對(duì)象
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:languageID];

如果您將語(yǔ)言ID作為區(qū)域設(shè)置ID參數(shù)傳遞,則會(huì)返回該語(yǔ)言的區(qū)域設(shè)置。 例如,如果您將de-CH作為語(yǔ)言傳遞,則會(huì)返回瑞士語(yǔ)言環(huán)境。

  • 獲取區(qū)域語(yǔ)言名稱
NSString *localizedString = [locale displayNameForKey:NSLocaleIdentifier value:languageID];

字符串的格式是[Language]([Dialect])。 例如,如果language IDde-CH,則本地化語(yǔ)言字符串是Deutsch(Schweiz)。如果語(yǔ)言ID是de,則本地化語(yǔ)言字符串是Deutsch。

4. Getting Language-Specific Quotes - 獲取特定于語(yǔ)言的引號(hào)

可以從區(qū)域設(shè)置對(duì)象獲取開(kāi)始和結(jié)束引號(hào),這些引號(hào)在不同的語(yǔ)言中有所不同。 使用Getting Localized Language and Dialect Names中描述的相同技術(shù)獲取該語(yǔ)言的默認(rèn)語(yǔ)言環(huán)境,然后使用區(qū)域鍵獲取特定于語(yǔ)言的引號(hào)。

To create a string that uses locale-sensitive quotes - 使用區(qū)域敏感引號(hào)創(chuàng)建字符串

  • 獲取APP正在使用的語(yǔ)言
NSString *languageID = [[NSBundle mainBundle] preferredLocalizations].firstObject;
  • 獲取關(guān)聯(lián)的區(qū)域?qū)ο?/li>
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:languageID];
  • 從區(qū)域?qū)ο笾蝎@取引號(hào)的開(kāi)始和結(jié)束符號(hào)
bQuote = [locale objectForKey:NSLocaleQuotationBeginDelimiterKey];
eQuote = [locale objectForKey:NSLocaleQuotationEndDelimiterKey];
  • 使用區(qū)域敏感的引號(hào)形成字符串
quotedString = [NSString stringWithFormat:@"%@%@%@", bQuote, myText, eQuote];

Table 4-2展示了不用區(qū)域,當(dāng)myText“@iPhone”的不同結(jié)果。

Table 4-2 Quotes in China, France, and Japan

Formatting Strings - 格式字符串

如果可用,請(qǐng)為面向用戶的文本使用替代的,區(qū)域敏感的NSString方法。 有語(yǔ)言環(huán)境敏感的方法來(lái)創(chuàng)建帶格式的字符串,更改大小寫,獲取字符串的range以及比較字符串。

1. Creating Formatted Strings - 創(chuàng)建格式字符串

至少,在NSString類中使用localizedStringWithFormat:方法,而不是使用stringWithFormat:方法來(lái)格式化面向用戶的文本。 對(duì)現(xiàn)有代碼的一個(gè)簡(jiǎn)單修復(fù)就是在整個(gè)代碼中用替代的localizedStringWithFormat:方法替換stringWithFormat:方法的出現(xiàn),如下所示:

NSString *localizedString = [NSString localizedStringWithFormat:@"%3.2f", myNumber];

此方法使用系統(tǒng)區(qū)域設(shè)置。 要指定用戶的區(qū)域設(shè)置首選項(xiàng),請(qǐng)將[NSLocale currentLocale]作為區(qū)域設(shè)置參數(shù)傳遞給initWithFormat:locale:initWithFormat:locale:arguments:方法。 為了獲得最佳結(jié)果,請(qǐng)使用Formatting Dates and Times以及Formatting Numbers中所述的數(shù)據(jù)特定格式化程序?qū)ο蠛皖A(yù)設(shè)樣式。

2. Changing the Case of Strings - 更改字符串的大小寫

在字符串中更改大小寫的過(guò)程對(duì)于所有語(yǔ)言都不相同。 使用這些區(qū)域敏感的NSString方法來(lái)更改大小寫:

如果您將nil作為區(qū)域設(shè)置參數(shù)傳遞,則會(huì)使用系統(tǒng)區(qū)域設(shè)置,這是不正確的。 要指定用戶的區(qū)域首選項(xiàng),請(qǐng)將[NSLocale currentLocale]作為語(yǔ)言環(huán)境參數(shù)傳遞。


Formatting Dates and Times - 格式化日期和時(shí)間

您可以使用NSDateFormatter類創(chuàng)建也是區(qū)域設(shè)置敏感的NSDate對(duì)象的本地化字符串表示。 NSDateFormatter對(duì)象通常直接附加到Interface Builder文件中的文本字段,但如果以編程方式創(chuàng)建NSDateFormatter對(duì)象,請(qǐng)確保使用返回本地化字符串表示形式的方法。

注意:NSDateFormatter類不是線程安全的。 詳情請(qǐng)參閱Threading Programming Guide。

1. Using Preset Date and Time Styles - 使用預(yù)設(shè)日期和時(shí)間樣式

要使用預(yù)設(shè)樣式獲取日期和時(shí)間的本地化字符串表示形式,請(qǐng)?jiān)?code>NSDateFormatter類中使用localizedStringFromDate:dateStyle:timeStyle:類方法:

NSString *localizedDateTime = [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterShortStyle];

例如,通過(guò)將NSDateFormatterMediumStyle作為style參數(shù)傳遞,指定一個(gè)中等樣式來(lái)縮寫文本(例如Jun 10, 2013)。 通過(guò)將NSDateFormatterShortStyle作為style參數(shù)傳遞,為僅限數(shù)字的表示(例如6/10/1311:03 AM)指定短樣式。 Table 4-3顯示了當(dāng)英語(yǔ)是該語(yǔ)言且美國(guó)是該地區(qū)時(shí)使用預(yù)設(shè)格式的結(jié)果。

Table 4-3 Preset date and time styles in English for the United States

Table 4-4顯示了針對(duì)日期樣式傳遞NSDateFormatterMediumStyle以及針對(duì)不同語(yǔ)言和區(qū)域傳遞時(shí)間樣式的NSDateFormatterShortStyle的結(jié)果。

Table 4-4 Preset date and time styles in different languages and regions

日期:WWDC 2013 Making Your App World-Ready: Data Formatting > Preset Date Styles

2. Using Custom Date and Time Styles - 使用自定義日期和時(shí)間樣式

僅當(dāng)預(yù)設(shè)樣式不符合您的需要時(shí)才使用自定義日期和時(shí)間樣式。 但是,在獲取日期和時(shí)間的字符串表示之前,請(qǐng)將自定義格式轉(zhuǎn)換為區(qū)域敏感的格式。 NSDateFormatter類中的dateFormatFromTemplate:options:locale:方法重新排列給定的模板以符合指定的區(qū)域。

To get a localized string representation of a date and time using a custom style - 使用自定義樣式獲取日期和時(shí)間的本地化字符串表示形式

NSDateFormatter *dateFormatter = [NSDateFormatter new];
NSString *localeFormatString = [NSDateFormatter dateFormatFromTemplate:@"dMMM" options:0 locale:dateFormatter.locale];

dateFormatFromTemplate:options:locale:方法的模板參數(shù)應(yīng)遵循Unicode Technical Standard #35,如Use Format Strings to Specify Custom Formats中所述。 例如,template @“dMMM”指定月份的日期和月份的縮寫應(yīng)該在格式字符串中。 模板中符號(hào)和任何非符號(hào)字符的順序都將被忽略。

  • NSDateFormatter實(shí)例的格式設(shè)置為區(qū)域設(shè)置敏感的格式字符串。
dateFormatter.dateFormat = localeFormatString;
  • 使用stringFromDate:方法獲取日期的本地化字符串表示形式。
NSString *localizedString = [dateFormatter stringFromDate:[NSDate date]];

例如,如果您不將@“MMM d”字符串轉(zhuǎn)換為區(qū)域設(shè)置敏感格式,則結(jié)果不是本地化的,如表4-5中的第二列所示

Table 4-5 Non-localized and localized date formats in different regions

視頻:WWDC 2013 Making Your App World-Ready: Date Formatting > Custom Date and Time Styles

3. Parsing Localized Date Strings - 解析本地日期字符串

用戶使用本地化格式輸入日期,因此相應(yīng)地解析輸入字符串。 使用NSDateFormatter對(duì)象將本地化的字符串轉(zhuǎn)換為日期對(duì)象。 使用其中一種預(yù)設(shè)樣式設(shè)置日期格式化器的樣式。 (僅當(dāng)預(yù)設(shè)樣式不起作用時(shí)才使用模板格式字符串。)另外,允許日期格式化程序在解析字符串時(shí)使用啟發(fā)式。

To convert a localized date string to a date object - 將本地化的日期字符串轉(zhuǎn)換為日期對(duì)象

  • 創(chuàng)建日期格式對(duì)象
NSDateFormatter *dateFormatter = [NSDateFormatter new];
  • 設(shè)置日期格式樣式為預(yù)設(shè)樣式
dateFormatter.dateStyle = NSDateFormatterMediumStyle;

NSDateFormatterMediumStyle替換為您希望用戶輸入的樣式。

  • 如果輸入字符串不包含時(shí)間,請(qǐng)將時(shí)間樣式設(shè)置為無(wú)。
dateFormatter.timeStyle = NSDateFormatterNoStyle;
  • leniency設(shè)置為YES(啟用heuristics)。
dateFormatter.lenient = YES;
  • 將字符串轉(zhuǎn)化為日期
NSDate *date = [dateFormatter dateFromString:inputString];

例如,如果區(qū)域?yàn)槊绹?guó),輸入字符串為9/3/14,預(yù)設(shè)樣式為NSDateFormatterShortStyle,則日期解釋為2014-09-03 07:00:00 +0000。 但是,如果區(qū)域設(shè)置為德國(guó),則日期變?yōu)?code>2014-03-09 08:00:00 +0000。


Formatting Numbers - 格式化數(shù)字

區(qū)域設(shè)置會(huì)影響數(shù)字的格式,例如小數(shù),千位分隔符,貨幣和百分比符號(hào)。 例如,意大利的數(shù)字1,234.56被格式化為1.234,56。 因此,使用NSNumberFormatter類來(lái)創(chuàng)建NSNumber對(duì)象的本地化字符串表示。

注意:NSNumberFormatter類不是線程安全的。 詳情請(qǐng)參閱Threading Programming Guide。

1. Using Preset Number Styles - 使用預(yù)設(shè)數(shù)組樣式

要使用預(yù)設(shè)樣式獲取數(shù)字的本地化字符串表示形式,請(qǐng)?jiān)?a target="_blank" rel="nofollow">NSNumberFormatter類中使用localizedStringFromNumber:numberStyle:方法:

表4-6列出了可用的預(yù)設(shè)樣式,并將美國(guó)預(yù)設(shè)格式與其他區(qū)域進(jìn)行比較

Table 4-6 Preset number styles in different languages and regions

視頻:WWDC 2013 Making Your App World-Ready: Number Formatting

2. Parsing Localized Number Strings - 解析本地?cái)?shù)字字符串

用戶可以使用本地化的格式輸入數(shù)字,因此可以相應(yīng)地解析這些輸入字符串。 使用NSNumberFormatter對(duì)象將字符串轉(zhuǎn)換為數(shù)字對(duì)象。 使用其中一種預(yù)設(shè)樣式設(shè)置數(shù)字格式化程序的樣式。 另外,允許數(shù)字格式化程序在解析字符串時(shí)使用啟發(fā)式。

To convert a localized number string to a number object - 將本地化的數(shù)字字符串轉(zhuǎn)換為數(shù)字對(duì)象

  • 創(chuàng)建一個(gè)數(shù)字格式化對(duì)象
NSNumberFormatter *numberFormatter = [NSNumberFormatter new];
  • 將格式化樣式設(shè)置為預(yù)設(shè)樣式
numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;

NSNumberFormatterDecimalStyle
替換為您希望用戶輸入的樣式。

  • 設(shè)置leniency為YES(啟用heuristics)
numberFormatter.lenient = YES;
  • 將字符串轉(zhuǎn)化為數(shù)字對(duì)象
NSNumber *number = [numberFormatter numberFromString:inputString];

Computing Dates Using Calendars - 使用日歷計(jì)算日期

NSCalendar類封裝了日歷的所有區(qū)域差異和復(fù)雜性,如表4-7所示。 era在某些日歷上的變化比其他日歷上更頻繁 - 例如,日歷中的era隨著每個(gè)新皇帝的變化而變化。 每年的月數(shù)可以是12或13個(gè)月。每個(gè)月的時(shí)間長(zhǎng)短可能會(huì)有所不同。 即使在公歷中,一周的第一天可能是周六,周日或周一。 NSCalendar對(duì)象了解時(shí)區(qū)以及哪些區(qū)域可以觀察夏令時(shí)。 日歷計(jì)算(如本月的第三個(gè)星期二)取決于用戶的日歷和地區(qū)。

Table 4-7 Variations in regional calendars

因此,對(duì)所有日歷計(jì)算使用NSCalendar類,例如計(jì)算一個(gè)月中的天數(shù),計(jì)算增量值以及獲取日期的組件。 您可以使用NSDate對(duì)象進(jìn)行內(nèi)部計(jì)算,但使用NSCalendar對(duì)象計(jì)算面向用戶的日期。

要獲取用戶區(qū)域設(shè)置的日歷,請(qǐng)?jiān)?code>NSCalendar類中使用currentCalendar類的方法:

NSCalendar *currentCalendar = [NSCalendar currentCalendar];

使用NSDateComponents對(duì)象獲取date的calendar units

To get the components of a date - 獲取date的組成

NSDateComponents *components = [[NSCalendar currentCalendar]
    components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSEraCalendarUnit
    fromDate:[NSDate date]];
  • 獲取時(shí)代、年、月和日的值。
NSInteger day = [components day];
NSInteger month = [components month];
NSInteger year = [components year];
NSInteger era = [components era];

提示:任何時(shí)候您獲取或設(shè)置年份,也可以獲取或設(shè)置era。 Era不是Gregorian calendar所必需的,但它對(duì)于其他幾種日歷是必須的。

有關(guān)使用NSCalendarNSDateComponents類的更多信息,請(qǐng)閱讀Date and Time Programming Guide或觀看WWDC 2013: Solutions to Common Date and Time Challenges。


Registering for Locale and Time Zone Changes - 注冊(cè)區(qū)域和時(shí)區(qū)更改

要接收區(qū)域設(shè)置更改通知,請(qǐng)將您的對(duì)象添加為NSCurrentLocaleDidChangeNotification通知的觀察者:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(localeDidChange :) name:NSCurrentLocaleDidChangeNotification object:nil];

要接收時(shí)區(qū)更改的通知,請(qǐng)觀察NSSystemTimeZoneDidChangeNotification通知。 例如,如果用戶在旅行,則在您的應(yīng)用運(yùn)行時(shí),時(shí)區(qū)可能會(huì)發(fā)生變化。 自上次您的應(yīng)用程序處于活動(dòng)狀態(tài)以來(lái)可能會(huì)過(guò)去很長(zhǎng)一段時(shí)間。

實(shí)施更改通知方法,以使用用戶的新區(qū)域設(shè)置重新格式化并顯示所有面向用戶的日期,時(shí)間和數(shù)字。

后記

本篇主要介紹了使用區(qū)域設(shè)置格式化數(shù)據(jù),感興趣的給個(gè)贊或者關(guān)注,謝謝~~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 你可以使用dateFromString:方法來(lái)創(chuàng)建一個(gè)代表日期的字符串,你也可以使用stringFromDate:...
    raingu24閱讀 2,867評(píng)論 0 1
  • 版本記錄 前言 很多APP都有國(guó)際化版本,常見(jiàn)于一些大公司的產(chǎn)品,比如Facebook、Wechat等,那么國(guó)際化...
    刀客傳奇閱讀 2,030評(píng)論 0 0
  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,737評(píng)論 0 5
  • 一周過(guò)去了,今天有時(shí)傳統(tǒng)節(jié)日端午節(jié) , 過(guò)了端午就意味著一年已過(guò)一半了 , 頓時(shí)覺(jué)得有點(diǎn)害怕,時(shí)間過(guò)得太快了, 還...
    八顆牙齒嗮太陽(yáng)閱讀 182評(píng)論 0 0
  • 多么可怕的母親。 人家都說(shuō)為母則強(qiáng),可是在七巧的身上,我只看到了瘋狂和可怕。 一個(gè)女人,因?yàn)榍鞍肷貌坏綈?ài),得不到...
    許孽閱讀 231評(píng)論 0 1

友情鏈接更多精彩內(nèi)容