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

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

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

文章目录

定位问题

经定位排查最终发现是俄罗斯的浮点数不是用小数点而是用逗号来分割的。在电脑的【控制面板——时钟和区域——其他设置】可以看到小数点的种类当然也能看到其他数据格式的分割符号。
在这里插入图片描述

分析问题找解决方案

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

方案一: 兼容不同国家的小数点分隔符在软件启动时设置一下使用统一的文化。
大体思路:软件启动前读取电脑控制面板的默认设置设置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那么就可以这么写代码:

        /// <summary>
        /// 多语言国际化问题
        /// </summary>
        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 比较麻烦。

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

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

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6