C# 国际化问题之CultureInfo(小数点的不同一些欧洲国家习惯使用,而非.)

前言
在公司做的桌面软件在国内以及亚美洲地区都能正常使用,结果到了俄罗斯客户那边软件就根本打不开,不能正常使用。

文章目录

        • 定位问题
        • 分析问题找解决方案
        • 总结

定位问题

经定位排查,最终发现是俄罗斯的浮点数不是用小数点,而是用逗号来分割的。在电脑的【控制面板——时钟和区域——其他设置】,可以看到小数点的种类,当然也能看到其他数据格式的分割符号。
C# 国际化问题之CultureInfo(小数点的不同一些欧洲国家习惯使用,而非.)_第1张图片

分析问题找解决方案

既然是不同区域的小数点分隔符号不一致导致的,那么就从这里入手,目前有两个解决方案。

方案一: 兼容不同国家的小数点分隔符,在软件启动时设置一下,使用统一的文化。
大体思路:软件启动前读取电脑控制面板的默认设置,设置CultureInfo的小数点符号,字符串和数字的转换时使用CultureInfo。

举个例子:
1、使用一个工具类记录小数点分割符号,以及数值的转换格式。

 class Utility
    {
        //记录小数点分隔符
        public static string NumberDecimalSeparator = ".";
        public const string NormalDot = ".";
        //数值转换格式
        public static NumberFormatInfo cusNumFormatInfo;
    }

2、在Main函数中获取控制面板中的设置

                   //获得和设置当前系统语言区域
                    string tempLanguage = "";
                    tempLanguage = System.Globalization.CultureInfo.InstalledUICulture.Name;

                    //区域文化 参考链接
                    //  https://docs.microsoft.com/zh-cn/dotnet/api/system.globalization.numberformatinfo?view=net-6.0

                    Utility.cusNumFormatInfo = CultureInfo.CreateSpecificCulture(tempLanguage).NumberFormat;
                    //获取小数点分隔符号
                    Utility.NumberDecimalSeparator = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;

                    Utility.cusNumFormatInfo.NumberDecimalSeparator = Utility.NumberDecimalSeparator;
                    Utility.cusNumFormatInfo.CurrencyDecimalSeparator = Utility.NumberDecimalSeparator;

3、使用例子
① 数值转字符串

  int  tempValue =  10;
  string tempValueStr = String.Format(Utility.cusNumFormatInfo,"{0:f2}",        Convert.ToUInt16(tempValue));
  // 假设使用的小数点分割符号是逗号,则
  // tempValueStr  = 10,00;

②字符串转数值

    string tempValueStr = "34,58";
    double tempValue =  Convert.ToDouble(tempValueStr , Utility.cusNumFormatInfo);
  // 假设使用的小数点分割符号是逗号,则
  // tempValue = 34.58;  //注:在软件调试的时候数值还是使用小数点做分割符号

但是也会有一个小缺点:在软件使用期间,控制面板的设置可能会被用户更改。

方案二: 忽略不同国家地区的小数点,统一使用点(.)作为小数点。
可以通过反射的方式设置CultureInfo,那么就可以这么写代码:

        /// 
        /// 多语言国际化问题
        /// 
        static void LoadSetting()
        {
            //欧洲国家的小数点为",",而中国的小数点是"."
            //设置语言文化为统一不变的文化
            SetDefaultCulture(CultureInfo.InvariantCulture);
        }

        static void SetDefaultCulture(CultureInfo culture)
        {
            Type type = typeof(CultureInfo);

            try
            {
                type.InvokeMember("s_userDefaultCulture",
                                    BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
                                    null,
                                    culture,
                                    new object[] { culture });

                type.InvokeMember("s_userDefaultUICulture",
                                    BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
                                    null,
                                    culture,
                                    new object[] { culture });
            }
            catch { }

            try
            {
                type.InvokeMember("m_userDefaultCulture",
                                    BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
                                    null,
                                    culture,
                                    new object[] { culture });

                type.InvokeMember("m_userDefaultUICulture",
                                    BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
                                    null,
                                    culture,
                                    new object[] { culture });
            }
            catch { }
        }

在Main函数调用LoadSetting之后,无论切换成什么语言环境,奇怪的多语言问题都迎刃而解了。 来自 C# 多语言国际化问题中的 CULTUREINFO,感谢大神的思路。

总结

方法一适用于客户提出需要按自己习惯方式输入和显示数值,缺点:在数值转换的地方都要用上数值格式化NumberFormatInfo ,比较麻烦。

方法二 比较简易方便。缺点:不能根据国家地区的习惯显示数值字符串。

如果无太大的需求推荐使用方法二。

你可能感兴趣的:(C#,c#,开发语言,visual,studio)