< 返回技术文档列表

App的国际化和本地化(五) —— 使用区域设置格式化数据(一)

发布时间:2022-11-15 22:09:21⊙投诉举报

版本记录

版本号时间
V1.02018.05.10

前言

很多APP都有国际化版本,常见于少量大公司的产品,比方Facebook、Wechat等,那么国际化需要我们APP做哪些更改呢,接下来这几篇就一起来看一下APP的国际化和本地化。感兴趣的可以看上面几篇。
1. App的国际化和本地化(一) —— 简单详情(一)
2. App的国际化和本地化(二) —— 查看语言和区域设置(一)
3. App的国际化和本地化(三) —— 国际化客户界面(一)
4. App的国际化和本地化(四) —— 国际化代码(一)

回顾

上一篇主要详情国际化代码,本篇主要详情使用区域设置格式化数据。


Formatting Data Using the Locale Settings - 使用区域设置格式化数据

不同的国家和地区对于数字和时间信息的格式有不同的商定。 区域设置提供有关当前客户使用的格式的信息,在编写解决面向客户的数据类型的代码时必需考虑这些信息。 客户通过在iOS设施的设置和Mac上的系统首选项中选择区域来设置区域设置。 客户还可以在应用程序运行时更改区域设置。 因而,假如您在代码中操作数据对象并将其呈现给客户,请使用locale APIs正确格式化数据。

您不需要知道如何格式化所有不同地区中的数据。 您可以使用自动生成区域敏感格式的预设样式。 只需您在将它们呈现给客户之前将其转换为区域性敏感格式,即可以使用自己设置格式。 本章详情如何编写区域敏感代码。


About Locale Formats - 关于区域格式

区域设置表示特定客户的格式选择,而不是客户的首选语言。 这些通常是相同的,但可以不同。 例如,住在德国的讲英语的母语人士可能会选择英语作为语言,德国作为该地区。 文本以英文显示,但日期,时间和数字遵循德国格式规则。 日在月的前面和24小时的时间表示,如Table 4-1所示。

Table 4-1 Data formats in United States and Germany

在Mac上,您可以在系统偏好设置中预览修改的区域设置首选项。 从“地区”弹出式菜单中选择地理区域时,会显示日期,时间和数字格式的样本。 该屏幕截图显示了当英语是该语言并且日本是该地区时的示例数据格式:

Mac客户还可以通过单击Advanced按钮来自己设置日期,时间和数字格式,如Reviewing Language and Region Preferences on Your Mac中所述。


Using the Locale Object - 使用地区对象

NSLocale对象封装有关特定区域的格式标准的信息。 在格式化面向客户的文本时,会传递一个代表客户所选区域的NSLocale对象。 NSLocale类提供用于获取客户的区域对象的类方法以及有关支持的区域的其余信息。

1. Getting the User’s Locale - 获取客户区域

您可以使用NSLocale类中的currentLocale或者autoupdatingCurrentLocale类方法来获取客户的区域。

假如使用currentLocale方法,则保证返回对象的属性值不会更改。 因而,假如要执行需要一致的操作,请使用currentLocale方法。

假如使用autoupdatingCurrentLocale方法,那么当客户更改区域设置时,属性值可能会更改。 但是,假如返回的对象发生更改,则不会通知您。

要观察区域设置首选项更改,请阅读Registering for Locale and Time Zone Changes。

提醒:系统设置与客户设置不同。 不要使用systemLocale类方法来获取客户的区域。

2. Getting Information About a Locale - 获取关于区域的信息

使用NSLocale类中的objectForKey:方法来访问有关语言环境的信息。 例如,将NSLocaleUsesMetricSystem密钥传递给此方法以获取布尔数,该数字确定区域设置能否使用metric系统。

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

传递key为NSLocaleCurrencySymbol以获取代表当地符号的字符串。

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

对于区域keys的完整列表,请参考NSLocale Component Keys

3. Getting Localized Language and Dialect Names - 获取本地语言和方言名称

不应向客户显示API和文件夹名称中指定语言和方言的标识符,例如de-CHen-AUpt-PT。 要取得可读的本地化语言或者方言名称,请在NSLocale类中使用displayNameForKey:value:方法,传递NSLocaleIdentifier作为关键参数。

To get the localized name for languages and dialects - 获取地区名称用于语言和方言

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

返回的字符串是标识书面语言或者方言的language ID,如Language and Locale IDs中所述。

  • 获取关联的地区对象
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:languageID];

假如您将语言ID作为区域设置ID参数传递,则会返回该语言的区域设置。 例如,假如您将de-CH作为语言传递,则会返回瑞士语言环境。

  • 获取区域语言名称
NSString *localizedString = [locale displayNameForKey:NSLocaleIdentifier value:languageID];

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

4. Getting Language-Specific Quotes - 获取特定于语言的引号

可以从区域设置对象获取开始和结束引号,这些引号在不同的语言中有所不同。 使用Getting Localized Language and Dialect Names中形容的相同技术获取该语言的默认语言环境,而后使用区域键获取特定于语言的引号。

To create a string that uses locale-sensitive quotes - 使用区域敏感引号创立字符串

  • 获取APP正在使用的语言
NSString *languageID = [[NSBundle mainBundle] preferredLocalizations].firstObject;
  • 获取关联的区域对象
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:languageID];
  • 从区域对象中获取引号的开始和结束符号
bQuote = [locale objectForKey:NSLocaleQuotationBeginDelimiterKey];eQuote = [locale objectForKey:NSLocaleQuotationEndDelimiterKey];
  • 使用区域敏感的引号形成字符串
quotedString = [NSString stringWithFormat:@"%@%@%@", bQuote, myText, eQuote];

Table 4-2展现了不用区域,当myText“@iPhone”的不同结果。

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

Formatting Strings - 格式字符串

假如可用,请为面向客户的文本使用替代的,区域敏感的NSString方法。 有语言环境敏感的方法来创立带格式的字符串,更改大小写,获取字符串的range以及比较字符串。

1. Creating Formatted Strings - 创立格式字符串

至少,在NSString类中使用localizedStringWithFormat:方法,而不是使用stringWithFormat:方法来格式化面向客户的文本。 对现有代码的一个简单修复就是在整个代码中用替代的localizedStringWithFormat:方法替换stringWithFormat:方法的出现,如下所示:

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

此方法使用系统区域设置。 要指定客户的区域设置首选项,请将[NSLocale currentLocale]作为区域设置参数传递给initWithFormat:locale:或者initWithFormat:locale:arguments:方法。 为了取得最佳结果,请使用Formatting Dates and Times以及Formatting Numbers中所述的数据特定格式化程序对象和预设样式。

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

在字符串中更改大小写的过程对于所有语言都不相同。 使用这些区域敏感的NSString方法来更改大小写:

  • uppercaseStringWithLocale:
  • lowercaseStringWithLocale:
  • capitalizedStringWithLocale:

假如您将nil作为区域设置参数传递,则会使用系统区域设置,这是不正确的。 要指定客户的区域首选项,请将[NSLocale currentLocale]作为语言环境参数传递。


Formatting Dates and Times - 格式化日期和时间

您可以使用NSDateFormatter类创立也是区域设置敏感的NSDate对象的本地化字符串表示。 NSDateFormatter对象通常直接附加到Interface Builder文件中的文本字段,但假如以编程方式创立NSDateFormatter对象,请确保使用返回本地化字符串表示形式的方法。

注意:NSDateFormatter类不是线程安全的。 介绍请参阅Threading Programming Guide

1. Using Preset Date and Time Styles - 使用预设日期和时间样式

要使用预设样式获取日期和时间的本地化字符串表示形式,请在NSDateFormatter类中使用localizedStringFromDate:dateStyle:timeStyle:类方法:

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

例如,通过将NSDateFormatterMediumStyle作为style参数传递,指定一个中等样式来缩写文本(例如Jun 10, 2013)。 通过将NSDateFormatterShortStyle作为style参数传递,为仅限数字的表示(例如6/10/13或者11:03 AM)指定短样式。 Table 4-3显示了当英语是该语言且美国是该地区时使用预设格式的结果。

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

Table 4-4显示了针对日期样式传递NSDateFormatterMediumStyle以及针对不同语言和区域传递时间样式的NSDateFormatterShortStyle的结果。

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 - 使用自己设置日期和时间样式

仅当预设样式不符合您的需要时才使用自己设置日期和时间样式。 但是,在获取日期和时间的字符串表示之前,请将自己设置格式转换为区域敏感的格式。 NSDateFormatter类中的dateFormatFromTemplate:options:locale:方法重新排列给定的模板以符合指定的区域。

To get a localized string representation of a date and time using a custom style - 使用自己设置样式获取日期和时间的本地化字符串表示形式

  • 创立NSDateFormatter对象
NSDateFormatter *dateFormatter = [NSDateFormatter new];
  • 使用dateFormatFromTemplate:options:locale:类方法从您提供的模板中获取一个本地化的格式字符串。
NSString *localeFormatString = [NSDateFormatter dateFormatFromTemplate:@"dMMM" options:0 locale:dateFormatter.locale];

dateFormatFromTemplate:options:locale:方法的模板参数应遵循Unicode Technical Standard #35,如Use Format Strings to Specify Custom Formats中所述。 例如,template @“dMMM”指定月份的日期和月份的缩写应该在格式字符串中。 模板中符号和任何非符号字符的顺序都将被忽略。

  • NSDateFormatter实例的格式设置为区域设置敏感的格式字符串。
dateFormatter.dateFormat = localeFormatString;
  • 使用stringFromDate:方法获取日期的本地化字符串表示形式。
NSString *localizedString = [dateFormatter stringFromDate:[NSDate date]];

例如,假如您不将@“MMM d”字符串转换为区域设置敏感格式,则结果不是本地化的,如表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 - 解析本地日期字符串

客户使用本地化格式输入日期,因而相应地解析输入字符串。 使用NSDateFormatter对象将本地化的字符串转换为日期对象。 使用其中一种预设样式设置日期格式化器的样式。 (仅当预设样式不起作用时才使用模板格式字符串。)另外,允许日期格式化程序在解析字符串时使用启发式。

To convert a localized date string to a date object - 将本地化的日期字符串转换为日期对象

  • 创立日期格式对象
NSDateFormatter *dateFormatter = [NSDateFormatter new];
  • 设置日期格式样式为预设样式
dateFormatter.dateStyle = NSDateFormatterMediumStyle;

NSDateFormatterMediumStyle替换为您希望客户输入的样式。

  • 假如输入字符串不包含时间,请将时间样式设置为无。
dateFormatter.timeStyle = NSDateFormatterNoStyle;
  • leniency设置为YES(启用heuristics)。
dateFormatter.lenient = YES;
  • 将字符串转化为日期
NSDate *date = [dateFormatter dateFromString:inputString];

例如,假如区域为美国,输入字符串为9/3/14,预设样式为NSDateFormatterShortStyle,则日期解释为2014-09-03 07:00:00 +0000。 但是,假如区域设置为德国,则日期变为2014-03-09 08:00:00 +0000


Formatting Numbers - 格式化数字

区域设置会影响数字的格式,例如小数,千位分隔符,货币和百分比符号。 例如,意大利的数字1,234.56被格式化为1.234,56。 因而,使用NSNumberFormatter类来创立NSNumber对象的本地化字符串表示。

注意:NSNumberFormatter类不是线程安全的。 介绍请参阅Threading Programming Guide

1. Using Preset Number Styles - 使用预设数组样式

要使用预设样式获取数字的本地化字符串表示形式,请在NSNumberFormatter类中使用localizedStringFromNumber:numberStyle:方法:

表4-6列出了可用的预设样式,并将美国预设格式与其余区域进行比较

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 - 解析本地数字字符串

客户可以使用本地化的格式输入数字,因而可以相应地解析这些输入字符串。 使用NSNumberFormatter对象将字符串转换为数字对象。 使用其中一种预设样式设置数字格式化程序的样式。 另外,允许数字格式化程序在解析字符串时使用启发式。

To convert a localized number string to a number object - 将本地化的数字字符串转换为数字对象

  • 创立一个数字格式化对象
NSNumberFormatter *numberFormatter = [NSNumberFormatter new];
  • 将格式化样式设置为预设样式
numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;

将NSNumberFormatterDecimalStyle
替换为您希望客户输入的样式。

  • 设置leniency为YES(启用heuristics)
numberFormatter.lenient = YES;
  • 将字符串转化为数字对象
NSNumber *number = [numberFormatter numberFromString:inputString];

Computing Dates Using Calendars - 使用日历计算日期

NSCalendar类封装了日历的所有区域差异和复杂性,如表4-7所示。 era在某些日历上的变化比其余日历上更频繁 - 例如,日历中的era随着每个新皇帝的变化而变化。 每年的月数可以是12或者13个月。每个月的时间长短可能会有所不同。 即便在公历中,一周的第一天可能是周六,周日或者周一。 NSCalendar对象理解时区以及哪些区域可以观察夏令时。 日历计算(如本月的第三个星期二)取决于客户的日历和地区。

Table 4-7 Variations in regional calendars

因而,对所有日历计算使用NSCalendar类,例如计算一个月中的天数,计算增量值以及获取日期的组件。 您可以使用NSDate对象进行内部计算,但使用NSCalendar对象计算面向客户的日期。

要获取客户区域设置的日历,请在NSCalendar类中使用currentCalendar类的方法:

NSCalendar *currentCalendar = [NSCalendar currentCalendar];

使用NSDateComponents对象获取date的calendar units

To get the components of a date - 获取date的组成

  • 创立一个NSDateComponents对象
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];

提醒:任何时候您获取或者设置年份,也可以获取或者设置era。 Era不是Gregorian calendar所必须的,但它对于其余几种日历是必需的。

有关使用NSCalendarNSDateComponents类的更多信息,请阅读Date and Time Programming Guide或者观看WWDC 2013: Solutions to Common Date and Time Challenges


Registering for Locale and Time Zone Changes - 注册区域和时区更改

要接收区域设置更改通知,请将您的对象增加为NSCurrentLocaleDidChangeNotification通知的观察者:

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

要接收时区更改的通知,请观察NSSystemTimeZoneDidChangeNotification通知。 例如,假如客户在旅行,则在您的应用运行时,时区可能会发生变化。 自上次您的应用程序处于活动状态以来可能会过去很长一段时间。

实施更改通知方法,以使用客户的新区域设置重新格式化并显示所有面向客户的日期,时间和数字。

后记

本篇主要详情了使用区域设置格式化数据,感兴趣的给个赞或者者关注,谢谢~~~~


/template/Home/Zkeys/PC/Static