【问题标题】:Parsing a value with decimal points [duplicate]解析带小数点的值[重复]
【发布时间】:2016-01-09 19:47:08
【问题描述】:

我有一个来自数据库的金额的字符串值。我系统上的当地文化是葡萄牙语(pt-br)。因此,具有小数值的金额被读取为,例如:3,4 表示 3.4。我需要以显示 3.4 的方式解析它,但无论我尝试什么,我都会得到 34。我已经在每个地方搜索了解决方案并尝试实现以下内容,但徒劳无功。

//这里的row[item.columnName]是我正在循环的DataTable的行

解决方案 1:

 Double amt = Double.Parse(Convert.ToString(row[item.columnName]), CultureInfo.InvariantCulture);

解决方案 2:

CultureInfo usCulture = new CultureInfo("en-US");
NumberFormatInfo dbNumberFormat = usCulture.NumberFormat;
Double amt = Double.Parse(Convert.ToString(row[item.columnName]), dbNumberFormat);

它们似乎都不起作用。有人可以建议我是否有其他方法可以实现这一目标?

编辑:

原来我从数据库中得到的值是十进制类型,所以我将我的 LOC 更改为以下。

decimal d = decimal.Parse(Convert.ToString(row[item.columnName]),new System.Globalization.CultureInfo("pt-BR", false));

它似乎仍然无法正常工作,我只是不知道哪里出错了。我在DotNetFiddle 上尝试了同样的事情 它工作得很好。下面是我试过的代码。

using System;

public class Program
{
    public static void Main()
    {
        decimal d = decimal.Parse("1,35",new System.Globalization.CultureInfo("pt-BR", false));
        Console.WriteLine(d.ToString());
    }
}

我得到的结果和预期的一样是 1.35。我做错了什么?

【问题讨论】:

  • 你能澄清一下:Convert.ToString(row[item.columnName]) 到底是什么字符串?如果它有一个逗号,那么将它解析为 InvariantCulture 当然是行不通的。您必须使用 PT-br 文化。
  • row[item.columnName].GetType() 已经是数字类型了吗?
  • 你真的在你的数据库中存储字符串吗?我怀疑,因为如果是这样,您将不需要Convert.ToString 电话。那么你的 db 列的类型是什么?

标签: c# parsing cultureinfo invariantculture


【解决方案1】:

你可以这样试试:

var x = decimal.Parse("yourDecimal", new NumberFormatInfo() { NumberDecimalSeparator = "," });

【讨论】:

    【解决方案2】:

    您可以使用葡萄牙文化信息

    CultureInfo usCulture = new CultureInfo("pt-PT", false);
    NumberFormatInfo dbNumberFormat = usCulture.NumberFormat;
    Double amt = Double.Parse(Convert.ToString(row[item.columnName]), dbNumberFormat);
    

    Double amt = Double.Parse(Convert.ToString(row[item.columnName]), new CultureInfo("pt-PT", false));
    

    【讨论】:

    • 这没有帮助。它给了我 3,4 的值,而我正在寻找 3.4
    • 嗨 Akshatha,我假设您的数据库和应用程序服务器都在 pt-br 中,因此在加载时您可能必须转换为国际或英语文化。如果您需要将双精度打印到屏幕上,则必须在 display Double amt = Double.Parse("1.233,4", new CultureInfo("pt-BR", false)); Console.WriteLine(amt); Console.WriteLine(amt.ToString(new CultureInfo("pt-BR", false))); Console.WriteLine(amt.ToString(new CultureInfo("en", false)));这对我有用
    【解决方案3】:

    如果您从数据库中获取双精度值,那么这不是解析问题。在 Solution 1 中,您将正确的双精度值转换为字符串(不指定任何文化,因此字符串将按葡萄牙语格式格式化),然后您解析具有不变文化的葡萄牙语字符串,其中 @987654321 @ 是千位分隔符。

    如果您想用英语文化格式化数字,您应该简单地设置当前文化英语:

    Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
    

    或者,只需在将双精度转换为字符串时指定文化:

    var en = CultureInfo.GetCultureInfo("en-US");
    // ...
    ((double)row[item.columnName]).ToString(en);
    

    【讨论】:

      【解决方案4】:

      也许row[item.columnName] 已经是doublerow[item.columnName].GetType() 返回什么?

      没有理由采用(盒装)double 并将其格式化为字符串(不指定文化),然后将该字符串解析回double(指定文化)。即使Convert.ToString 有一个将IFormatProvider(可能是CultureInfo)作为第二个参数的重载。

      也许

      double amt = (double)row[item.columnName];
      

      会有用吗?如果您有decimal,请使用decimal amt = (decimal)row[item.columnName];double amt = (double)(decimal)row[item.columnName];

      如果row[item.columnName].GetType() 真的是字符串,则转换为:

      double amt = Double.Parse((string)row[item.columnName], someGoodCulture);
      

      我个人不喜欢Convert.ToString,因为很难看出它是否只是向下转换了已经存在的string,或者它格式化了一些IFormattable实例(例如doubledecimal)到当前线程的当前文化,或者只是在某个任意对象上调用.ToString()

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-19
        • 1970-01-01
        • 2019-12-03
        • 2018-04-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多