国际化在您的项目

你在实际工作中如何实施国际化(i18n)?

在我读完Joel着名的“绝对最低限度的每个软件开发人员”之后,我对编程软件的兴趣越来越浓厚,积极肯定Unicode和字符集(没有任何借口!) 。 但是,我还没有能够利用这个实际项目,除了确保我使用Unicodestring在可能的情况下。 但是把所有的string做成Unicode,并且确保你理解你所使用的所有东西的编码只是国际冰山的一angular。

我所做过的所有工作都是由一群受控制的美国说英语的人来使用的,或者说,在推动这个项目之前,我们并没有时间去做这件事。 所以我正在寻找人们在现实世界中使软件更加本地化的技巧或战争故事。

已经有一段时间了,所以这不是全面的。

字符集

Unicode很好,但是你不能忽略其他字符集。 Windows XP(英文)上的默认字符集是Cp1252。 在networking上,你不知道浏览器会发送给你什么(尽pipe希望你的容器能处理大部分的内容)。 当你正在使用的任何实现中存在缺陷时,不要感到惊讶。 字符集在移动到机器之间时可以与文件名进行有趣的交互。

翻译string

翻译者一般来说不是编码员。 如果您将源文件发送给翻译人员,他们会将其分解。 应将string提取到资源文件(例如Java中的属性文件或Visual C ++中的资源DLL)。 应该给翻译人员提供难以打破的文件,以及不让他们破译的文件。

翻译者不知道产品的string来自哪里。 没有上下文的情况下翻译string是很困难的。 如果您不提供指导,翻译的质量将受到影响。

在上下文的主题中,您可能会多次看到相同的string“foo”,并认为将UI中的所有实例指向相同的资源会更高效。 这是一个坏主意。 在某些语言中,单词可能会非常敏感。

翻译string需要花费金钱。 如果您发布新版本的产品,则恢复旧版本是有意义的。 有工具从旧的资源文件恢复string。

string串联和手动操作的string应尽量减less。 使用适用的格式function。

翻译者需要能够修改热键。 Ctrl + P是英文打印; 德国人使用Ctrl + D。

如果您的翻译过程需要某人随时手动剪切和粘贴string,那么您正在寻求麻烦。

date,时间,日历,货币,数字格式,时区

这些都可以因国而异。 逗号可以用来表示小数点。 时间可能在24小时的表示法中。 不是每个人都使用公历。 你也需要明确的。 如果您注意在您的网站上显示date为美国的MM / DD / YYYY和英国的DD / MM / YYYY,date是模棱两可的,除非用户知道您已经完成。

特别是货币

类库中提供的区域设置function将为您提供当地的货币符号,但是您不能在以美元为单位的价格之前粘贴英镑(或英镑)或欧元符号。

用户界面

布局应该是dynamic的。 不仅翻译string的长度可能翻倍,整个UI可能需要颠倒(希伯来语;阿拉伯语),以便控件从右向左运行。 那是在我们到达亚洲之前。

翻译前的testing

  • 使用代码的静态分析来查找问题。 至less,利用IDE中内置的工具。 (Eclipse用户可以转到Window> Preferences> Java> Compiler> Errors / Warnings并检查非外部string。)
  • 模拟翻译的烟雾testing。 parsing一个资源文件并用一个伪翻译的版本replacestring并不难,这个伪翻译的版本将长度加倍并插入时髦的字符。 您无需使用外语操作系统就可以使用语言。 现代系统应该让你以翻译string和国外语言环境的外国用户身份login。 如果你熟悉你的操作系统,你可以知道什么是不知道一个单词的语言。
  • 键盘映射和字符集引用是非常有用的。
  • 虚拟化在这里非常有用。

非技术问题

有时你必须对文化差异敏感(可能导致犯罪或不理解)。 您经常看到的一个错误是使用标志作为select网站语言或地理的视觉线索。 除非你希望你的软件在全球政治中宣布双方,否则这是一个坏主意。 如果你是法国人,并且提供圣乔治国旗的英文选项(英格兰的国旗是一个白色的领域的红十字),这可能会导致许多英语人士的困惑 – 假设外语和国家会出现类似的问题。 图标需要审查文化的相关性。 什么是竖起大拇指或绿色的勾号是什么意思? 语言应该是相对中立的 – 以特定的方式处理用户在一个地区可能是可以接受的,但在另一个地区被认为是粗鲁的。

资源

C ++和Java程序员可能会发现ICU网站很有用: http : //www.icu-project.org/

一些有趣的事情:

  1. 拥有适用于德语和法语的PHP和MySQL应用程序,但现在需要支持俄语和中文。 我想我把这个移到.net,因为PHP的Unicode支持在我看来并不是很好。 当然,用utf8_de / encode或者mbstring函数来玩耍是很有趣的。 几乎和弗雷迪·克鲁格在晚上拜访你一样有趣…

  2. 意识到一些语言比其他语言更胜一筹。 德语通常比英语更冗长,并且看到德语版本如何破坏用户界面,因为分配太less的空间并不好玩。 一些产品因其创造性的解决方法而获得了一些成功,湮没的“Schw.Ler.Le.En.W.” 令人难忘:-)

  3. 玩date格式,呜呼! 是的,世界上实际上有人使用中间的date格式。 Sooooo很有趣,试图找出07/02/2008是什么意思,只是因为有些用户可能会相信它可能是7月2日…但是,再次,你们在池塘上可能会相信用户谁把中间一个月:-P,特别是因为在英语中,7月2日听起来比7月2日好得多,这种东西不一定适用于其他语言(例如德语中,你永远不会说Juli 2,但总是Zweiter Juli)。 我尽可能使用2008-02-07。 很明显,这意味着2月7日,它适当的sorting,但月/毫米与毫米/月是一个非常棘手的问题。

  4. 非常有趣的东西, 数字格式 ! 10.000,50比10,000.50比10,000,50比10'000,50 …这是我现在最大的噩梦,不得不支持多文化的环​​境,但没有办法可靠地知道用户的数字格式将使用。

  5. 正式的或非正式的。 在某种语言中,有两种方式可以解决人们的问题,一种是正式的方式,另一种是非正式的方式。 在英语中,你只是说“你”,但在德国,你必须在正式的“西”和非正式的“杜”之间做出决定,同法国图/ Vous一样。 select正式的方式通常是安全的,但这很容易被忽视。

  6. 日历。 在欧洲,本周的第一天是星期一,而在美国是星期天。 日历小工具很好。 在左侧和星期六的欧洲用户右侧显示日历并不是很好,它会让他们感到困惑。

我曾经为我以前使用.NET的雇主开发了一个项目,并且使用了.resx格式。 我们基本上有一个文件,在.resx文件中有所有的翻译,然后有不同翻译的多个文件。 这样做的结果是,您必须非常勤奋,确保应用程序中可见的所有string都存储在.resx中,并且只要您更改了所有语言,就必须更新所支持的所有语言。

如果你懒惰,不通知负责翻译的人,或者你没有通过你的本地化系统embeddedstring,那么以后尝试修复它将是一场噩梦。 同样,如果本地化是事后考虑的话,这将是非常困难的。 底线,如果您没有在标准地方存储所有可见的string,那么将很难find所有需要进行本地化的string。

另一个注意事项是,非常严格地避免直接连接可见string,例如

String message = "The " + item + " is on sale!"; 

相反,你必须使用类似的东西

 String message = String.Format("The {0} is on sale!", item); 

原因是不同的语言经常以不同的顺序排列,直接连接string需要一个新的构build来修复,但是如果你使用了上面的某种stringreplace机制,你可以修改.resx文件(或者任何本地化您使用的文件)为需要重新sorting单词的特定语言。

今天早上我只是在听斯科特·汉塞尔曼(Scott Hanselman)的播客 ,谈论国际化,尤其是像土耳其(四个人)和泰国人那样的非常棘手的事情。 另外,杰夫·阿特伍德还有一个post

除了之前的所有提示之外,请记住,国际化不仅仅是要改变其他语言的文字,尤其是非拉丁语言的字母(韩文,阿拉伯文),因为这样做会影响到整个UI,

  • 第1项
  • 第2项
  • 第3项

必须是

阿拉伯文本1 –

阿拉伯文字2 –

阿拉伯文本3 –

(反转的子弹名单似乎不工作:P)

如果您的系统必须在用户更改正在使用的语言之后应用更改,则这可能是UI恶梦。

另一个非常难的是testing不同的语言,不仅仅是为了正确的单词,但是由于像韩文这样的语言通常对字符有更大的字体types,这可能导致语言特定的错误(比如button上的“保存”文本大于一些语言的button本身)。

其中一个有趣的事情发现:斜体和粗体文字makrup不适用于CJK(中国/日本/韩国)字符。 他们只是变得不可读。 (好吧,在我之前我都不能真正阅读它们,但是特别是大胆创build墨迹)

我认为在国际化工作的每个人都应该熟悉Common Locale Data Repository,它现在是Unicode的一个子项目:

Common Locale Data Repository

这些人正在努力为各种国际性的问题build立一个标准的资源:货币,地理名称,吨数。 因为这个项目的存在,任何维护自己的核心本地数据的项目都是非常好的,恕我直言。

我build议使用类似99translations.com来维护你的翻译。 否则,您将无法分辨您的翻译在每种语言中是最新的。

另一个挑战将是接受来自用户的input。 在许多情况下,这可以通过操作系统提供的input处理(如Windows中的IME)使用普通文本小部件透明地进行处理来缓解,但是该function并不适用于所有可能的需求。

我使用的一个网站有一个翻译方法,所有者称之为“wiki +机器翻译”。 这是一个基于社区的网站,与公司的需求明显不同。

http://blog.bookmooch.com/2007/09/23/how-bookmooch-does-its-translations/

没有人提到过的一件事就是“单位会在五天之内”或者“星期一发生什么事”。 5和星期一将根据状态改变。 把它们分成两部分并连接起来并不是一个好主意。 只有一个不同的部分和良好的文档,你可能会摆脱它,有两个不同的部分会有一些语言,最喜欢改变他们的顺序。