版本记录
版本号 | 时间 |
---|---|
V1.0 | 2018.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所示。
在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-CH
,en-AU
和pt-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 ID
是de-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”
的不同结果。
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方法来更改大小写:
如果您将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-4显示了针对日期样式传递NSDateFormatterMediumStyle
以及针对不同语言和区域传递时间样式的NSDateFormatterShortStyle
的结果。
日期: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中的第二列所示
视频: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列出了可用的预设样式,并将美国预设格式与其他区域进行比较
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对象了解时区以及哪些区域可以观察夏令时。 日历计算(如本月的第三个星期二)取决于用户的日历和地区。
因此,对所有日历计算使用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
所必需的,但它对于其他几种日历是必须的。
有关使用NSCalendar
和NSDateComponents
类的更多信息,请阅读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通知。 例如,如果用户在旅行,则在您的应用运行时,时区可能会发生变化。 自上次您的应用程序处于活动状态以来可能会过去很长一段时间。
实施更改通知方法,以使用用户的新区域设置重新格式化并显示所有面向用户的日期,时间和数字。
后记
本篇主要介绍了使用区域设置格式化数据,感兴趣的给个赞或者关注,谢谢~~~~