42th Unicode Conference随笔(一)

三国曹丕的《典论·论文》中说:“文人相轻,自古而然。”这话其实还有后句的,叫“武人相重”。而我辈应当算作文人?抑或武人呢?窃以为还是偏武多一些,毕竟IT圈儿的主流依然是“夜里挑灯看剑,梦回吹角连营”,吟风弄月的怀橘陆郎多半难成气候。然而面对业内充斥着的各种不厌其烦发明着的轮子,倒也不禁难掩大家平实外表下文人骚客的风骨。毕竟“文无第一,武无第二”,别人提供的框架、代码库怎么都觉得差点儿意思,还是得老夫亲自披坚执锐来打造自己眼中的白月光,心头的朱砂痣。稍加润色,又一个业内的incredible game changer就这样的伴着祥瑞轰隆而至。别的不说,一个小小的国际化前端生态圈,就可以如此的山头林立,以至于城头变幻大王旗成了家常便饭,同时务必需要注意的是,仍有一大波changer正在赶来的路上。

42th Unicode Conference随笔(一)

 

照片来42th Unicode Conference现场

 

目光重新回到这小小的国际化前端生态圈儿吧,来自AWS的Alolita Sharma女士在她的slides中详解了GlobalizeJS的新特性。在笔者参加的几个有限session中,Alolita带来的What’s New with GlobalizeJS应该算是稳居三甲了。但作为GlobalizeJS这样开源前端库的拥趸,本文并不想大谈特谈其新特性,反其道而行之,说说What’s Old吧,用一个个的示例来看看他已经为我们带来了什么。

 

为了一睹真容,首先要做的是按照https://github.com/globalizejs/globalize READE.md中Getting Started进行部署。

npm install globalize
npm install cldr-data
npm install iana-tz-data

这个过程如遇错误,请耐心重试。接下来我会按照如下几个模块进行效果展示。

时间

var Globalize = require( "globalize" );
Globalize.load( require( "cldr-data" ).entireSupplemental() );
Globalize.load( require( "cldr-data" ).entireMainFor( "fr", "de", "zh", "zh-Hant", "ja", "ko", "pt", "ar", "ru") );
Globalize.loadTimeZone( require( "iana-tz-data" ) );

var d1 = Globalize("fr").dateFormatter({ datetime: "full"})(new Date());
console.log(d1);

var d2 = Globalize("de").dateFormatter({ datetime: "full"})(new Date());
console.log(d2);

var d3 = Globalize("zh").dateFormatter({ datetime: "full"})(new Date());
console.log(d3);

var d4 = Globalize("zh-Hant").dateFormatter({ datetime: "full"})(new Date());
console.log(d4);

var d5 = Globalize("ja").dateFormatter({ datetime: "full"})(new Date());
console.log(d5);

var d6 = Globalize("ko").dateFormatter({ datetime: "full"})(new Date());
console.log(d6);

var d7 = Globalize("pt").dateFormatter({ datetime: "full"})(new Date());
console.log(d7);

var d8 = Globalize("ar").dateFormatter({ datetime: "full"})(new Date());
console.log(d8);

var d9 = Globalize("ru").dateFormatter({ datetime: "full"})(new Date());
console.log(d9);

打印结果如下。

mardi 25 septembre 2018 à 14:20:00 UTC+08:00
Dienstag, 25. September 2018 um 14:20:00 GMT+08:00
2018年9月25日星期二 GMT+08:00 下午2:20:00
2018年9月25日 星期二 下午2:20:00 [GMT+08:00]
2018年9月25日火曜日 14時20分00秒 GMT+08:00
2018년 9월 25일 화요일 오후 2시 20분 0초 GMT+08:00
terça-feira, 25 de setembro de 2018 14:20:00 GMT+08:00
الثلاثاء، ٢٥ سبتمبر ٢٠١٨ ٢:٢٠:٠٠ م غرينتش+٠٨:٠٠
вторник, 25 сентября 2018 г., 14:20:00 GMT+08:00

货币

var cash = 999999;
console.log( Globalize("fr").currencyFormatter("EUR")(cash) );
console.log( Globalize("fr").currencyFormatter("EUR", { style: "name" })(cash) );
console.log( Globalize("fr").currencyFormatter("EUR", { style: "code" })(cash) );

console.log( Globalize("ja").currencyFormatter("JPY")(cash) );
console.log( Globalize("ja").currencyFormatter("JPY", { style: "name" })(cash) );
console.log( Globalize("ja").currencyFormatter("JPY", { style: "code" })(cash) );

console.log( Globalize("zh-Hant").currencyFormatter("HKD")(cash) );
console.log( Globalize("zh-Hant").currencyFormatter("HKD", { style: "name" })(cash) );
console.log( Globalize("zh-Hant").currencyFormatter("HKD", { style: "code" })(cash) );

结果如下。

999 999,00 €
999 999,00 euros
999 999,00 EUR

¥999,999
999,999円
999,999JPY

HK$999,999.00
999,999.00 港幣
999,999.00 HKD

数字

var num = 123456789.123;
console.log( Globalize("fr").numberFormatter()(num) );
console.log( Globalize("de").numberFormatter()(num) );
console.log( Globalize("zh").numberFormatter()(num) );
console.log( Globalize("zh-Hant").numberFormatter()(num) );
console.log( Globalize("ja").numberFormatter()(num) );
console.log( Globalize("ko").numberFormatter()(num) );
console.log( Globalize("pt").numberFormatter()(num) );
console.log( Globalize("ar").numberFormatter()(num) );
console.log( Globalize("ru").numberFormatter()(num) );

输出如下。

123 456 789,123
123.456.789,123
123,456,789.123
123,456,789.123
123,456,789.123
123,456,789.123
123.456.789,123
١٢٣٬٤٥٦٬٧٨٩٫١٢٣
123 456 789,123

单位

var count = 9;
console.log( Globalize("fr").unitFormatter("mile-per-hour", { form: "long" })(count) );
console.log( Globalize("de").unitFormatter("mile-per-hour", { form: "long" })(count) );
console.log( Globalize("zh").unitFormatter("mile-per-hour", { form: "long" })(count) );
console.log( Globalize("zh-Hant").unitFormatter("mile-per-hour", { form: "long" })(count) );
console.log( Globalize("ja").unitFormatter("mile-per-hour", { form: "long" })(count) );
console.log( Globalize("ko").unitFormatter("mile-per-hour", { form: "long" })(count) );
console.log( Globalize("pt").unitFormatter("mile-per-hour", { form: "long" })(count) );
console.log( Globalize("ar").unitFormatter("mile-per-hour", { form: "long" })(count) );
console.log( Globalize("ru").unitFormatter("mile-per-hour", { form: "long" })(count) );

显示如下。

9 miles par heure
9 Meilen pro Stunde
每小时9英里
每小時 9 英里
時速 9 マイル
시속 9마일
9 milhas por hora
٩ ميل في الساعة
9 миль в час

复数

Globalize.loadMessages({
  en: {
    task: [
      "You have {count, plural,",
      "     =0 {no task}",
      "    one {one task}",
      "  other {{formattedCount} tasks}",
      "} remaining"
    ]
  }
});

numberFormatter = Globalize("en").numberFormatter();
taskFormatter = Globalize("en").messageFormatter( "task" );

console.log(taskFormatter({
  count: 1000,
  formattedCount: numberFormatter(1000)
}));

console.log(taskFormatter({
  count: 1,
  formattedCount: numberFormatter(1)
}));

console.log(taskFormatter({
  count: 0,
  formattedCount: numberFormatter(0)
}));

映入眼帘的文字如下。

You have 1,000 tasks to do!
You have one task to do!
You have no task to do!

不难发现GlobalizeJS作为一个前端i18n库已经足够细节和优秀了,思之再三仍无法给自己一个另起炉灶,再做轮子的动机和理由。即便面对某些场景不那么完美时,我们为何不拥抱她,加入她呢?古人云:“独乐乐,与人乐乐,孰乐乎?不若与人”诚哉斯言!