使用文化信息将逗号十进制值转换为点十进制值的最佳方法

Posted

技术标签:

【中文标题】使用文化信息将逗号十进制值转换为点十进制值的最佳方法【英文标题】:The best way of converting comma decimal values to dot decimal values using culture info 【发布时间】:2015-11-09 06:44:20 【问题描述】:

您好,我需要根据文化信息转换一个十进制值。 对于 EG

如果 en-US 文化,十进制值将类似于 21.56 并且在 tr-TR 是土耳其文化信息,这里的值与 21,56

相同

Si 我的要求是任何十进制值,但我需要默认进入 en-US。我需要用点分隔的十进制值,我不想要逗号的十进制值。

我尝试使用以下代码进行转换

                CultureInfo userCulture = new CultureInfo("tr-TR");
                string fromVisioAPI = "35,2083";
                string display = double.Parse(fromDb, userCulture).ToString();

这里的输出是“35.2083”,这是我的预期,但这里是硬编码 tr-TR 值,我不知道有多少文化具有相同的逗号和点差异。

This was a normal replacement and i need to be a proper culture conversion

那么是什么..?

【问题讨论】:

你不能,一般来说。 “21,123”可能表示“21,100,1023”,也可能表示“仅比 21 多一点”。这取决于文化。您需要了解文化才能理解价值。 @JonSkeet 所以它的赌注是输入一个字符串并用点替换逗号..? 我不知道您所说的“赌注”是什么意思 - 但我的意思是,除非您了解文化,否则您无法可靠地理解其价值。您绝对应该只用点替换逗号,因为那样会改变意思。 对不起更好,不赌 好的,所以答案基本上是“不,不要那样做”。 【参考方案1】:

您需要知道要解析的数据的文化信息。如果那是静态的,您可以简单地对其进行硬编码或在app.config 中配置它。 否则你可以使用CultureInfo.CurrentCulture

要将值转换回字符串,您应该使用带有特定文化信息的 ToString 重载:

var visioApiCulture = 
    new CultureInfo(ConfigurationManager.AppSettings["VisioApiCulture"]);

var visioApiCulture = CultureInfo.CurrentCulture;

-

string fromVisioApi = "35,2083";

string display = double
    .Parse(fromVisioApi, visioApiCulture)
    .ToString(CultureInfo.InvariantCulture);

【讨论】:

【参考方案2】:

假设 Visio API 与您的代码在同一台计算机上运行,​​那么 Visio 使用的 Windows 文化信息很可能与您的程序默认使用的相同。您可以从 CultureInfo.CurrentCulture 属性中获取当前文化:https://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.currentculture(v=vs.110).aspx

【讨论】:

【参考方案3】:

它认为below code 可以帮助你..

public double? ConvertStringToDouble(string strDoubleValue)

    //Checking null
    if (strDoubleValue == null)
    
        return null;
    

    //Making trim
    strDoubleValue = strDoubleValue.Trim();

    //Checking empty
    if (strDoubleValue == string.Empty)
    
        return null;
    

    //If the amout treat dot(.) as decimal separator
    if (strDoubleValue.IndexOf('.')!=-1)
    
        //If multiple . is present then the amount is invaid
        if (strDoubleValue.Count(o=>o=='.')>1)
        
            return null;
        

        //removing thousand separators
        //it might not be needed
        strDoubleValue = strDoubleValue.Replace(",", "");

        return ConvertPlainStringToDouble(strDoubleValue);
    


    //If the amout treat dot(,) as decimal separator
    //then it must not use ',' as thousand separator
    if (strDoubleValue.Count(o => o == ',') > 1)
    
        //removing thousand separators
        //it might not be needed
        strDoubleValue = strDoubleValue.Replace(",", "");
        return ConvertPlainStringToDouble(strDoubleValue);                
    

    //Here will be logic that the string contains single comma , is treated here as 
    //deciaml separator or comma separator

    //int charCountBeforeComma = strDoubleValue.IndexOf(',');
    //int charCountAfterComma = strDoubleValue.Length - (charCountBeforeComma + 1);

    ////If charCountAfterComma is not in 3rd position than
    ////the comma cannot be thousand separator example: 458,5896
    //if (charCountAfterComma!=3)
    //
    //    //removing thousand separators
    //    //it might not be needed
    //    strDoubleValue = strDoubleValue.Replace(",", ".");
    //    return ConvertPlainStringToDouble(strDoubleValue);   
    //

    //if string having more than 3 char before comma like 4589,548
    //it means no thousand separator used else the amount should represent like this 4,589,548
    //you can use below code 
    //if (charCountBeforeComma>3)
    //
    //    //removing thousand separators
    //    //it might not be needed
    //    strDoubleValue = strDoubleValue.Replace(",", "");
    //    return ConvertPlainStringToDouble(strDoubleValue);   
    //

    //if all above missed than i am sorry              
    //it means the string is like 458,458 or 58,458 format
    //you need to put some logical condition here 
    //??????



private Double? ConvertPlainStringToDouble(string strPlainDoubleValue)
            
    Double amount;
    if (Double.TryParse(strPlainDoubleValue, out amount))
    
        return amount;
    

    return null;

我试图通过所有合乎逻辑的条件来解决问题 .. 但最终 .. 有一些事情需要解决 d由你填写.. :)

【讨论】:

这仍然是一个猜谜游戏,无论如何它只考虑小数点和千位分隔符 - 还有很多其他事情可以破坏解析。您首先假设的是,如果有.,则意味着它必须是小数点。这完全不正确 - 1.123.456,50 是一个完全有效的数字 - 包括像 german 这样的深奥语言(事实上,在 .NET 中有 92 种文化 使用这种格式!)。 【参考方案4】:

您应该在 API 中使用通用格式属性 - 这些属性不依赖于文化设置。

例如,要获取单元格的公式,请使用 FormulaU - 这将保留 . 中的所有数字表示小数点,, 表示千位分隔符格式。

使用Result 也应该有效,因为它应该返回一个双精度,而不是一个字符串 - 如果你得到一个字符串,要么你使用了不正确的互操作库,要么你做错了什么。您可以再次使用ResultStrU 作为解决方法来获取通用格式字符串。

【讨论】:

以上是关于使用文化信息将逗号十进制值转换为点十进制值的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

无论文化如何,查找十进制值的小数位数

运行时十进制符号更改

详细请教:关于十进制RGB颜色值转换十六进制颜色值的算法

c#十进制toString()用逗号(,)转换

将包含十六进制值的字节数组转换为十进制值

使用 CsvHelper 时转换为十进制