国际化是指在设计和开发应用时,使应用能够适应不同语言、地区和文化的过程。它不仅仅是简单的语言翻译,还涉及到日期、时间、数字、货币、度量衡、时区与夏令时等多种格式的适配,以及界面布局、图标、颜色等元素的通用设计。国际化的目标是创建一个可以在全球范围内使用的应用,而无需对代码进行大量修改。例如,在国际化的应用中,日期格式可能根据用户所在地区显示为不同的样式,如“YYYY-MM-DD”(中国)或“MM/DD/YYYY”(美国)。
本地化则是在国际化的基础上,针对特定的目标语言和地区,对应用进行定制和优化的过程。这包括将应用的界面文本翻译成当地语言、调整界面布局以适应不同的文字长度和阅读习惯(RTL)、使用当地的文化元素和符号等。本地化确保应用在每个目标市场都能提供自然、流畅且符合当地用户期望的体验。例如,将一款英语应用本地化到日本,不仅要将文本翻译成日语,还可能需要调整界面布局以适应日语字符的显示,以及使用日本的文化元素来增强用户亲和力。
国际化侧重于构建应用的通用框架和基础架构,使其具备支持多种语言和文化的能力(个人理解:国际化是系统已经构建的通用能力);而本地化则是针对具体的语言和地区,对应用进行个性化的适配和优化(个人理解:本地化是需要开发者适配的部分)。国际化是一种全局的、前瞻性的设计理念,而本地化是在国际化的基础上,针对特定市场的实际落地和实施。
国际化与本地化优势、国际化与本地化官方指南、@ohos.i18n (国际化-I18n)官方API、Localization Kit(本地化开发服务)官方API(包括ArkTS API(@ohos.i18n、@ohos.intl、@ohos.resourceManager、@ohos.sendableResourceManager)、C API、错误码)、
国际化与本地化官方指南(Localization Kit(本地化开发服务))目录如下:
国际化和本地化概述应用国际化 国际化界面设计区域ID与文化习惯划分语言与用户偏好 系统语言与区域应用偏好语言用户偏好 时间日期国际化数字与度量衡国际化电话号码格式化设置日历和历法时区与夏令时国际化 时区夏令时跳变 多语言排序 概述本地习惯排序创建索引 字符处理本地化名称 概述本地化语言与地区名称本地化时区名称 应用本地化 提供多语言资源提升可翻译性 避免硬编码与拼接提供翻译场景支持单复数 本地化测试 伪本地化测试 伪本地化测试概述翻译伪本地化测试界面镜像伪本地化测试 语言测试在鸿蒙(HarmonyOS)应用开发中,
@ohos.intl 和
@ohos.i18n 是两个共同为应用提供国际化(i18n)能力的模块,但它们在职责和功能上有明确的划分。
| 特性维度 | @ohos.intl | @ohos.i18n |
|---|---|---|
| 遵循标准 | ECMA 402 标准 | 鸿蒙增强和补充接口 |
| 核心功能 | 基础的、与语言文化相关的数据格式化 | 系统相关的、更深层次的区域和文化服务 |
| 主要应用场景 | 格式化日期、时间、数字、货币;字符串排序 | 获取/设置系统语言地区;本地化显示文本;日历、电话号码处理等 |
除了文本,日期、时间、数字和货币等数据也需要根据区域设置进行格式化。鸿蒙的
@ohos.intl 模块(或
@kit.LocalizationKit 中的
i18n 模块)提供了相关API。
注意处理夏令时跳变,确保应用在夏令时期间显示正确的时间。可以使用
Calendar 类来获取和设置时区、计算夏令时相关的时间偏移等。
使用 i18n.DateTimeUtil.formatDate(date, options),根据用户所在地区的语言和文化习惯,将日期对象格式化为合适的字符串。
import i18n from '@kit.LocalizationKit'; // 或根据实际SDK调整导入方式
const now = new Date();
// 假设用户设备区域设置为 'zh-CN'
const formattedDate = i18n.DateTimeUtil.formatDate(now, { locale: 'zh-CN' });
console.log(formattedDate); // 输出示例: 2025/12/25
使用鸿蒙的
@ohos.intl模块(国际化API)格式化日期。
import intl from '@ohos.intl';
const now = new Date();
// 获取用户设备的区域设置(如zh-CN/en-US)
const locale = 'zh-CN'; // 实际可通过系统API动态获取:intl.getLocale()
// 格式化日期(intl.formatDate会根据传入的locale参数自动选择符合当地习惯的日期格式(无需手动判断语言))
this.currentDate = intl.formatDate(now, {
year: 'numeric',
month: '2-digit',
day: '2-digit',
locale: locale
});
通过 i18n.NumberUtil.formatNumber(number, options)接口,根据用户地区设置,对数字/货币进行格式化,包括小数分隔符、分组显示、货币符号等。例如:
import i18n from '@kit.LocalizationKit';
const number = 123456.78;
const formattedNumber = i18n.NumberUtil.formatNumber(number, { locale: 'de-DE', style: 'currency', currency: 'EUR' });
console.log(formattedNumber); // 输出示例: 123.456,78 €
import intl from '@ohos.intl';
const amount = 1234.56;
const locale = 'zh-CN'; // 实际可通过系统API获取
this.price = intl.formatNumber(amount, {
style: 'currency',
currency: 'CNY', // 人民币(根据locale动态选择:如en-US用USD)
locale: locale
});
static getDisplayCountry(country: string, locale: string, sentenceCase?: boolean): string
参数说明:
country (string, 必填):需要被翻译的国家或地区代码,例如 "CN" 代表中国,"US" 代表美国。这个代码通常遵循 ISO 3166 标准。
locale (string, 必填):目标区域ID,指定了你希望将国家名称翻译成哪种语言和地区格式。它由语言、脚本、国家/地区等部分组成,例如 "en-GB" 代表英式英语。
sentenceCase (boolean, 可选):控制返回的文本是否首字母大写。默认为
true。
返回值:
类型:
string
说明:返回指定国家或地区在目标语言环境下的本地化名称。
鸿蒙允许应用在运行时动态切换语言,以提供更灵活的用户体验。
设置应用偏好语言:你可以使用
i18n.System.setAppPreferredLanguage(language: string
) 为你的应用设置特定的语言,这不会影响整个系统的语言设置。
import i18n from '@kit.LocalizationKit';
// 将应用偏好语言设置为简体中文
try {
i18n.System.setAppPreferredLanguage('zh-Hans');
// 设置成功后,需要重新加载界面以应用新语言
} catch (error) {
console.error(`设置应用偏好语言失败,错误码: ${error.code}, 消息: ${error.message}`);
}
获取系统语言信息:你也可以获取系统的当前语言、地区等信息,以便做出相应的适配。
import i18n from '@kit.LocalizationKit';
// 获取系统语言
const systemLanguage = i18n.System.getSystemLanguage();
console.log(systemLanguage); // 示例: "ug", "bo", "zh-Hant", "en-Latn-US", "zh-Hans"
// 获取系统地区
const systemRegion = i18n.System.getSystemRegion();
console.log(systemRegion); // 示例: 'CN'
// 获取系统区域标识
const systemLocale = i18n.System.getSystemLocale();
console.log(systemLocale); // 示例: 'zh-Hans-CN'
string.json(或其他资源文件)被打包到应用的
resources目录中,按语言子目录分类存储。运行时检测:应用启动时,鸿蒙系统读取用户设备的当前语言设置(如
Settings.System.LANGUAGE)。动态匹配:根据设备语言(如
zh-CN),优先加载对应语言的资源文件(如
resources/zh_CN/element/string.json);若未找到匹配语言,则回退到默认语言(如
resources/base/element/string.json)。UI渲染:ArkUI框架将代码中的资源引用(如
$string:welcome_text)替换为实际加载的文本内容,完成界面渲染。
zh-CN→
zh-Hans→
en-US→默认)。格式适配:日期、数字、货币等通过国际化API自动匹配地区规则。
鸿蒙采用特定的目录结构来管理多语言资源。资源目录包括默认(base)目录和限定词目录(如 resources/en_GB-vertical-car-mdpi)。默认目录存放通用资源,限定词目录根据语言、文字等自定义,用于存放特定区域的资源。
创建资源目录:
在相应目录下创建资源文件(如 .json 文件),将字符串、图片、音频等资源分类存放。例如,在项目的
resources 目录下,为每种支持的语言创建子目录。子目录说明如下:
美式英文资源:
resources/en_US/element/string.json
简体中文资源:
resources/zh_CN/element/string.json
默认资源(如英文):
resources/base/element/string.json
定义字符串资源:在每个目录的
string.json 文件中定义对应语言的字符串。
resources/base/element/string.json (默认,通常用英文)
{
"string": [
{
"name": "welcome_message",
"value": "Hello, world!"
},
{
"name": "login_button",
"value": "Login"
}
]
}
resources/zh_CN/element/string.json (简体中文):
{
"string": [
{
"name": "welcome_message",
"value": "你好,世界!"
},
{
"name": "login_button",
"value": "登录"
}
]
}
在UI代码中,通过引用的方式动态加载资源。资源匹配规则如下。
资源匹配规则:应用根据用户的语言偏好列表与资源目录进行匹配,优先显示最匹配的资源。如果未找到匹配资源,则使用默认目录下的内容。
注意:鸿蒙中资源引用通常通过
$r('app.string.资源名')(需在
resources/base/profile/main_pages.json中配置资源路径),或直接使用
$string:资源名。
ArkUI声明式开发范式:使用
$r 或
$string 语法引用资源。
// 使用 $r 语法
Text($r('app.string.welcome_message'))
.fontSize(24)
// 或者使用 $string 语法
Button($string('login_button'))
.onClick(() => {
// 处理点击事件
})
string.json资源文件定义如下:
// 资源文件路径: src/main/resources/base/element/string.json
{
"string": [
{
"name": "test",
"value": "I'm a %1$s, format int: %2$d, format float: %3$f."
}
]
}
代码中通过getStringSync方法获取带参数字符串。示例如下:
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
try {
// 'app.string.test'仅作示例,请替换为实际使用的资源
let testStr = this.context.resourceManager.getStringSync($r('app.string.test').id, "format string", 10, 98.78);
console.info(`getStringSync, result: ${testStr}`);
// 打印输出结果: getStringSync, result: I'm a format string, format int: 10, format float: 98.78.
} catch (error) {
let code = (error as BusinessError).code;
let message = (error as BusinessError).message;
console.error(`getStringSync failed, error code: ${code}, message: ${message}.`);
}
}
}
通过function $r(value: string, ...params: any[]): Resource;方法获取带参数字符串。示例如下:$r('app.string.test','home',8,10.1)展示结果为"I'm a home, format int: 8, format float: 10.1"
在鸿蒙应用中,主要通过资源文件定义和API调用两种方式来实现单复数适配。
你需要在项目的
resources 目录下,为每种支持的语言创建对应的plural资源文件(如
en-US.json),并在其中定义复数字符串。
不同语言的单复数规则不同,国际上常使用
zero,
one,
two,
few,
many,
other 这些类别来区分。例如:
英语等语言通常有
one (单数) 和
other (复数) 两种形式。
中文一般不严格区分单复数,通常只使用
other 类别。
阿拉伯语等语言则可能拥有上述全部六种形式。
以下是资源文件定义的示例:
en-US.json (英语-美国)
{
"plural": [
{
"name": "format_test",
"value": [
{
"quantity": "one",
"value": "There is %d apple in the %s, the total amount is %f kg."
},
{
"quantity": "other",
"value": "There are %d apples in the %s, the total amount is %f kg."
}
]
}
]
}
定义好资源后,你可以在代码中通过相应的API来获取匹配的字符串
使用ResourceManager API:对于更底层的开发,可以使用
getPluralStringValue 或
getPluralString 等同步/异步方法。使用详情参考getIntPluralStringValueSync的API文档,注意第二个参数传字符串中单复数的值,系统通过这个参数判断使用哪种单复数的字符串。
可以使用function $r(value: string, ...params: any[]): Resource;方法获取单复数字符串,注意需要仿照
getPluralStringValue方法在第二个参数处传输单复数值。例如:$r('app.plural.format_test',10,10,'home',8)展示结果为"There are 10 apples in the home, the total amount is 8 kg."
语言环境差异:务必了解目标语言的单复数规则。中文等语言通常不区分单复数,所有数量都可能匹配到
other 规则。
提供默认规则:为确保健壮性,资源文件中至少应包含
other 规则,作为找不到匹配时的回退方案。
关注API版本:部分单复数相关的API(如
getPluralString)在较新版本中可能已被标记为废弃,建议关注官方文档,使用最新的推荐API(如
getPluralStringValue)。
避免硬编码:所有面向用户的字符串、图片等资源都不应直接写在代码里,而应放入资源文件。
布局灵活性:设计UI布局时要考虑文本长度变化和阅读习惯(RTL)。避免因文字翻译后长度不同导致布局错乱,例如,德语文本通常比英语长,而中文文本可能较短;避免不符合当地阅读习惯(RTL),如阿拉伯语。
建立回退机制:如果应用找不到与当前设置完全匹配的语言资源,应有一套回退策略(例如,回退到默认的
base 目录下的资源),以保证应用基本功能正常。
全面测试:需要在支持的所有语言环境下进行测试,检查文本显示、布局、日期、数字、货币格式等是否正确。特别注意从右到左(RTL)语言(如阿拉伯语)的布局适配。