朱利安· 莫茨 ( Julian Motz) , 帕纳约提斯· 维利萨拉科斯 ( Panayiotis Velisarakos) , 维尔丹 ·史蒂芬 ( Vildan Softic)和蒂姆·塞维里安 ( Tim Severien)对此文章进行了同行评审。 感谢所有SitePoint的同行评审人员使SitePoint内容达到最佳状态!
因此,您是从事下一件大事的开发人员。 您的客户喜欢您的产品,并且在所有社交网络上都获得好评。 更好的是,该公司的首席执行官刚刚获得了1000万美元的融资,以拓展新市场。 但是在走向全球之前,必须先更新产品以支持不同的语言,货币,日期格式等。 你猜怎么着? 您和您的团队是实现这一目标的负责人。 用技术术语来说,您的软件必须先进行国际化然后本地化。
国际化 (也称为i18n )是创建或转换产品和服务的过程,以便可以轻松地使其适应特定的本地语言和文化。 本地化 (也称为L10n )是使国际化软件适应特定地区或语言的过程。 换句话说,国际化是使您的软件适应多种文化(货币格式,日期格式等)的过程,而本地化是实现一种或多种文化的过程。
这两个过程通常由在不同国家/地区具有利益的公司采用,但是对于在自己的网站上工作的单个开发人员来说,它们也可能会派上用场。 例如,您可能知道,我是意大利人,并且拥有一个网站。 我的网站目前使用英语,但我可能会决定对其进行国际化,然后将其本地化为意大利语。 对于那些以意大利语为母语但不太习惯英语的人来说,这是有益的。
在本文中,我将向您介绍Globalize ,这是一个由jQuery团队的成员开发的用于国际化和本地化的JavaScript库。 本文演示的所有代码片段都可以在我们的GitHub存储库中找到。
但是在深入研究全球化之前,我想以项目负责人Rafael Xavier de Souza的话来结束关于i18n的简短介绍:
开发人员认为i18n与非英语语言的翻译有关。 只有将当前应用程序扩展到多个国家或市场才需要i18n。 我总是试图解释i18n通常是关于“交谈”的。 在某个时候,每个应用程序都必须与其用户“对话”。 为了与用户交谈,该应用程序可能需要多元化支持,性别变化,日期格式,数字格式和货币格式。 即使使用英语,正确完成此操作也可能很棘手。
Globalize是用于国际化和本地化的JavaScript库,它利用了官方Unicode CLDR JSON数据。
该库是开源的,由Rafael Xavier de Souza和jQuery团队的一些成员共同开发。
Globalize基于Unicode联盟的通用语言环境数据存储库(CLDR) ,它是现有的最大和最广泛的语言环境数据标准存储库。 因此,与嵌入语言环境数据的库不同,如果您使用Globalize,则始终可以始终保持最新的CLDR数据非常容易。
该库既适用于浏览器,也可用作Node.js模块。 Globalize 1.0支持所有主要浏览器,包括IE9 +,Chrome,Firefox,Safari 5.1+和Opera 12.1+。
该库的主要功能是:
我最喜欢Globalize的一件事是它为每个功能都有一个模块。 开发人员可能不需要整个库,因此可以挑选所需的模块。 另一个有趣的功能是,与其他库不同,它不通过在库中托管或嵌入任何语言环境数据来使代码与内容分离。
但是全球化并不是镇上唯一的演出。 如果您对某些替代方法感兴趣,那么Rafael会有一个专门的页面 。 最值得注意的替代方法是i18next 。
对于您中的某些人来说,这可能令人惊讶,但是JavaScript以国际化API (也称为ECMA-402)的形式对国际化提供了本机支持。 Intl
对象是在window
对象上可用的对象,该对象充当国际化API的命名空间。 该API当前提供了格式化数字和日期以及比较特定语言的字符串的方法。
既然您已经知道了国际化API的存在,您可能会被认为是Globalize在后台使用它。 这种方法肯定会导致更好的日期和数字格式设置性能。 但是,由于支持程度很低,并且浏览器之间的支持非常不一致 ,因此该库不使用它。
在继续进行全球化讨论之前,我想向您介绍一下国际化API。
我将展示的第一个示例使用国际化API在几种语言环境中格式化日期:IT,美国和GB。
// 30th of June 2016
var date = new Date(2016, 5, 30);
// "30/6/2016"
console.log(new Intl.DateTimeFormat('it-IT').format(date));
// "6/30/2016"
console.log(new Intl.DateTimeFormat('en-US').format(date));
// "30/06/2016"
console.log(new Intl.DateTimeFormat('en-GB').format(date));
在此示例中,我使用DateTimeFormat
构造函数使用指定的语言环境(“ it-IT”,“ en-US”和“ en-GB”)创建新的日期格式程序。 然后,我调用format
方法来格式化日期对象。
上面的代码也可以作为JSBin使用 。
如前所述,API还允许您格式化数字。 下面显示了一个使用NumberFormat
构造函数的示例:
var number = 1302.93;
// "1.302,93"
console.log(new Intl.NumberFormat('it-IT').format(number));
// "1,302.93"
console.log(new Intl.NumberFormat('us-US').format(number));
// "1,302.93"
console.log(new Intl.NumberFormat('en-GB').format(number));
通过查看第二个代码段(也可以作为JSBin获得)的输出,您会注意到,在意大利,我们对数字的格式设置与美国和英国相比有所不同。
如前所述,对该API的支持很低,但如果要使用它,可以在应用程序中使用此polyfill 。
现在,我对国际化和本地化的工作方式有了更好的了解,让我们讨论全球化。
可以通过npm轻松安装Globalize:
npm install globalize cldr-data --save
该命令还安装CLDR数据,这对于加载Globalize将要使用的语言环境数据(例如,如何以某种语言格式化数字或日期)是必需的。 安装了这两个软件包后,我们就可以使用该库了。
注意 :以下示例假定使用Node。 如果您有兴趣在浏览器中使用Globalize,建议从项目主页上的示例之一开始。 该webpack示例使启动和运行起来特别容易。
接下来,我将使用Globalize重写上一节中列出的两个代码段。
可以如下所示实现第一个示例:
// Include the Globalize library
var Globalize = require('globalize');
// Include the CLDR data
var cldrData = require('cldr-data');
// Loads the supplemental data
Globalize.load(cldrData.entireSupplemental());
// Loads the data of the specified locales
Globalize.load(cldrData.entireMainFor('it', 'en', 'en-GB'));
// 30th of June 2016
var date = new Date(2016, 5, 30);
// "30/6/2016"
console.log(Globalize('it').formatDate(date));
// "6/30/2016"
console.log(Globalize('en').formatDate(date));
// "30/06/2016"
console.log(Globalize('en-GB').formatDate(date));
尽管它很简单,但是上面的代码使我可以涵盖一些主题。 第一次玩Globalize时,第一件令我感到有些奇怪的事情是,CLDR数据使用的某些语言代码仅使用两个字母。 为了保持一致,我希望所有语言环境都要求使用ISO 3166标准的完整版本(例如“ it-IT”和“ en-US”),而不是简短版本(例如“ it”和“ en”)。 尽管假设意大利的意大利语为默认设置似乎合法(意大利人毕竟起源于意大利),但英语却令人困惑。 实际上,“ en”代表美式英语,而不是英式英语。 如果您想确保不要犯与我相同的错误,建议您看一下这张桌子 。
值得概述的另一个概念是整个entireSupplemental
方法(代码的第三条语句)。 这将加载所有包含国家或地区数据补充信息的文件。 例如电话国家/地区代码(意大利为39),人口,一些著名的缩写,如何拼写其他国家/地区的货币等等。
我要介绍的最后一点是第四条语句,在该语句中调用了entireMainFor
方法。 这允许加载所需国家(在上面的示例中是意大利,美国和英国)的语言环境数据。
要格式化数字,Globalize提供了formatNumber
方法。 该方法的签名是
formatNumber(value[, options])
其中value
是要格式化的数字,而options
是用于自定义方法返回值的对象。 您可以指定的选项的一些示例是:
round
:定义数字如何取整。 其值可以是以下任意值: ceil
, floor
, round
或truncate
useGrouping
:一个布尔值,指示是否应使用分组分隔符 minimumIntegerDigits
:一个非负整数,指示要使用的最小整数数字。 可用选项的完整列表可在文档中找到 。
现在我们已经了解了有关formatNumber
方法的更多信息,让我们来看一下它的实际作用。
// Include the Globalize library
var Globalize = require('globalize');
// Include the CLDR data
var cldrData = require('cldr-data');
// Loads the supplemental data
Globalize.load(cldrData.entireSupplemental());
// Loads the data of the specified locales
Globalize.load(cldrData.entireMainFor('it', 'en', 'en-GB'));
var number = 1302.93;
// "1.302,93"
console.log(Globalize('it').formatNumber(number));
// "1,302.93"
console.log(Globalize('en').formatNumber(number));
// "1,302.93"
console.log(Globalize('en-GB').formatNumber(number));
该库提供了currencyFormatter
方法来帮助您格式化货币值。 此方法支持许多选项,这些选项可让您定义是否要四舍五入,是否要使用货币符号(例如“ $”)或其代码(例如“ USD”)等等。
下面显示了使用currencyFormatter()
的示例:
// Include the Globalize library
var Globalize = require('globalize');
// Include the CLDR data
var cldrData = require('cldr-data');
// Loads the supplemental data
Globalize.load(cldrData.entireSupplemental());
// Loads the data of the specified locales
Globalize.load(cldrData.entireMainFor('en'));
var enGlobalize = Globalize('en');
var value = 229.431;
var usdFormatter = enGlobalize.currencyFormatter('USD');
// "$229.43"
console.log(usdFormatter(value));
var eurFormatter = enGlobalize.currencyFormatter('EUR', {
style: 'code',
round: 'ceil'
});
// "229.44 EUR"
console.log(eurFormatter(value));
解析数字也可能是您必须执行的任务,也许是在处理用户输入时。 以下示例演示了如何执行此操作:
// Include the Globalize library
var Globalize = require('globalize');
// Include the CLDR data
var cldrData = require('cldr-data');
// Loads the supplemental data
Globalize.load(cldrData.entireSupplemental());
// Loads the data of the specified locales
Globalize.load(cldrData.entireMainFor('en'));
// Set default locale
var enGlobalize = Globalize('en');
var numberParser = enGlobalize.numberParser();
// "229.431"
console.log(numberParser('229,431.00'));
var percentParser = enGlobalize.numberParser({style: 'percent'});
// "0.5341"
console.log(percentParser('53.41%'));
现代Web应用程序中另一个非常常见的功能是以相对的方式显示时间和日期。 例如,通常不显示一天的完整日期,而是查找诸如“昨天”和“上周”之类的标签。 借助relativeTimeFormatter
方法,使用Globalize轻松完成此任务。 使用示例如下所示:
// Include the Globalize library
var Globalize = require('globalize');
// Include the CLDR data
var cldrData = require('cldr-data');
// Loads the supplemental data
Globalize.load(cldrData.entireSupplemental());
// Loads the data of the specified locales
Globalize.load(cldrData.entireMainFor('en'));
// Set default locale
var enGlobalize = Globalize('en');
var dayFormatter = enGlobalize.relativeTimeFormatter('day');
// "yesterday"
console.log(dayFormatter(-1));
var yearFormatter = enGlobalize.relativeTimeFormatter('year');
// "next year"
console.log(yearFormatter(1));
全球化提供了许多本文未介绍的其他方法。 但是,这里介绍的主题应该已经为您提供了足够的信息来使您入门和运行。 此外,图书馆的文件非常详细。
在本文中,我讨论了什么是国际化和本地化以及它们为什么对扩大产品市场很重要。 我通过提及一些受支持的功能向您简要介绍了国际化API,然后,展示了一些使用它们的示例。
在本文的第二部分中,我向您介绍了Globalize,这是jQuery团队开发的用于国际化和本地化的JavaScript库。 该库功能非常强大,并提供了使项目国际化所需的所有方法,例如:解析数字,格式化日期和格式化货币值的方法。 如果您认为图书馆为您节省了时间,请随时为该项目做点贡献。
再次提醒您,可以在我们的GitHub存储库中找到本文演示的所有代码段。
From: https://www.sitepoint.com/how-to-implement-internationalization-i18n-in-javascript/