快一年没写过博客了。最近在项目中吃了两次同样的亏,还是记录一下,让后来者有所参考。

最近的项目中准备全盘国际化,所以理所当然地直接使用了.NET的国际化方案。自己依葫芦画瓢地用T4根据生成各种语言包;让2哥改写了MVC3的部分引擎;杰哥实现了JavaScript和CSS的国际化。然后在一个本来宁静的晚上迎来了第一个里程碑,期间各种bug与补丁齐飞,鬼故事讲了一晚上,办公室贴满了苍老师(你懂的)的题字“厉害”,“梦想很美”等等之类,皆略去不说。最后卡在一个怪异的问题上面:部分用户购买过程中价格的小数点丢了。好他礼貌用语地奇怪啊!找了一晚上,一边瞌睡一边找,睡完继续找,托着脖子找,最后让2哥发现了端倪。原来有些语言习惯中(如西班牙语、法语)小数点是作为千位分隔符使用的,逗号才起小数点的作用。而我们在新旧系统对接的时候无可避免地使用了文本传递数据。这样一来旧系统的$0.78一经转换就变成了$78。客人估计被坑惨了吧?更背的是我们的国际化现阶段是根据用户浏览器的首选语言来确定语言的,因此我们的各式中英文浏览器全部阵亡,无一能重现这个bug(除非改首选语言,不过当时没想到这么多)。而唯一一个使用法语Mac系统的运维同学一直在围观,没有亲自动手,杯具……

昨天早上奇怪的事情又一次发生了。运费计算时好时坏,得到的结果跟正确结果相比没有固定的规律。而多数用户得到的又还是正确结果,只有少数用户,如某人花了$2.x买了一条数据线,缺心眼儿地非要EMS过去,结果收了人家$200+运费,然后他还NC地付款了……这个问题的纠结过程丝毫不低于上个问题。又由于memcached和开发人员都爱选某便宜物品作为测试商品的共同作用,bug一再难以重现。最后结果还是很简单的,某另一项目组的同事给我们的DLL中从配置文件读取了汇率和一个计算因子,都是用.作为小数点的,当用户使用西班牙语和法语等语种的时候又杯具了而由于是两个数字,互相作用造成结果看起来没有明显规律,蒙了我们好久。

所以总结一下,遇到小数点丢失问题或数值运算结果太离谱的同学,先仔细想想是否做了国际化,Thread.CurrentCulture会影响你的ToString和Parse/TryParse行为,务必小心。同时因为是在线程中设置的,不止你的代码会受影响,第三方代码如果考虑不周一样会受影响。解决办法是:

1. 全盘国际化。如果需要转换的字符串转换结果全部都有相同的区域语言设置,自然就绕过不一致的问题了。当然实际情况是过渡时期很难全盘国际化,所以需要方案2。

2. 转换的时候使用CultureInfo.InvariantCulture作为参数强制使用文化无关的格式。

posted on 2011-09-20 23:52  yaoxing  阅读(545)  评论(0编辑  收藏  举报