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

版本記錄

版本號 時間
V1.0 2018.05.10

前言

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

回顧

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


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

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

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


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

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

Table 4-1 Data formats in United States and Germany

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

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


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

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

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

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

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

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

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

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

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

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

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

傳遞key為NSLocaleCurrencySymbol以獲取代表當(dāng)?shù)胤柕淖址?/p>

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

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

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

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

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

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

返回的字符串是標識書面語言或方言的language ID,如Language and Locale IDs中所述。

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

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

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

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

4. Getting Language-Specific Quotes - 獲取特定于語言的引號

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

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

  • 獲取APP正在使用的語言
NSString *languageID = [[NSBundle mainBundle] preferredLocalizations].firstObject;
  • 獲取關(guān)聯(lián)的區(qū)域?qū)ο?/li>
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:languageID];
  • 從區(qū)域?qū)ο笾蝎@取引號的開始和結(jié)束符號
bQuote = [locale objectForKey:NSLocaleQuotationBeginDelimiterKey];
eQuote = [locale objectForKey:NSLocaleQuotationEndDelimiterKey];
  • 使用區(qū)域敏感的引號形成字符串
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ū)域敏感的NSString方法。 有語言環(huán)境敏感的方法來創(chuàng)建帶格式的字符串,更改大小寫,獲取字符串的range以及比較字符串。

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

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

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

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

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

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

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


Formatting Dates and Times - 格式化日期和時間

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

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

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

要使用預(yù)設(shè)樣式獲取日期和時間的本地化字符串表示形式,請在NSDateFormatter類中使用localizedStringFromDate:dateStyle:timeStyle:類方法:

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

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

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

Table 4-4顯示了針對日期樣式傳遞NSDateFormatterMediumStyle以及針對不同語言和區(qū)域傳遞時間樣式的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 - 使用自定義日期和時間樣式

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

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

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)該在格式字符串中。 模板中符號和任何非符號字符的順序都將被忽略。

  • NSDateFormatter實例的格式設(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對象將本地化的字符串轉(zhuǎn)換為日期對象。 使用其中一種預(yù)設(shè)樣式設(shè)置日期格式化器的樣式。 (僅當(dāng)預(yù)設(shè)樣式不起作用時才使用模板格式字符串。)另外,允許日期格式化程序在解析字符串時使用啟發(fā)式。

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

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

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

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

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


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

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

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

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

要使用預(yù)設(shè)樣式獲取數(shù)字的本地化字符串表示形式,請在NSNumberFormatter類中使用localizedStringFromNumber:numberStyle:方法:

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

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 - 解析本地數(shù)字字符串

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

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

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

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

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

Computing Dates Using Calendars - 使用日歷計算日期

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

Table 4-7 Variations in regional calendars

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

要獲取用戶區(qū)域設(shè)置的日歷,請在NSCalendar類中使用currentCalendar類的方法:

NSCalendar *currentCalendar = [NSCalendar currentCalendar];

使用NSDateComponents對象獲取date的calendar units。

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

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

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

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


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

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

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

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

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

后記

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

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

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

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

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