简体   繁体   English

将货币字符串转换为十进制?

[英]Convert currency string to decimal?

Objective客观的

Sort a string that is displaying currency data like this $1,995.94 numerically in a set of data.在一组数据中以数字方式对显示货币数据的string进行排序,例如$1,995.94

Code代码

I'm currently using the below code sample to convert the string value to decimal so that I can sort it properly.我目前正在使用下面的代码示例将string值转换为decimal ,以便我可以正确排序。

if (sortBy == "checkAmount")
{
    StringBuilder sb = new StringBuilder();
    foreach (var c in Convert.ToString(p.GetType().GetProperty(sortBy).GetValue(p, null)))
    {
        if (!char.IsDigit(c) && c != '.') { continue; }
        sb.Append(c);
    }
    return Convert.ToDecimal(sb.ToString());
}
else
{
    return p.GetType().GetProperty(sortBy).GetValue(p, null);
}

Problem问题

What's a better way of doing this?有什么更好的方法来做到这一点? It works, and that's cool, but it's not very elegant.它有效,这很酷,但它不是很优雅。

Final Solution最终解决方案

The answer provided by Servy works as expected , and I used that implementation for a while, but a colleague and I found an even better way so I'm documenting it here. Servy 提供的答案按预期工作,我使用了该实现一段时间,但我和一位同事找到了更好的方法,所以我在这里记录它。 BTW, I ended up using this solution in the end.顺便说一句,我最终使用了这个解决方案。

decimal.Parse(input, NumberStyles.AllowCurrencySymbol | NumberStyles.Number);

How about this, but only works for one string value.这个怎么样,但只适用于一个字符串值。 So you need to get your string split by $ and then do the conversion while saving into the array or list因此,您需要将字符串按$ split ,然后在保存到arraylist的同时进行转换

 using System.Globalization;
    //rest of your code

          string str = "$50,550.20";
          decimal decval;
          bool convt = decimal.TryParse(str, NumberStyles.Currency,
            CultureInfo.CurrentCulture.NumberFormat, out decval);
          if (convt) 
          Console.WriteLine(decval);
          Console.ReadLine();

Here is a simpler solution:这是一个更简单的解决方案:

    public static decimal ToDecimal(this string str)
    {
        return decimal.Parse(str, NumberStyles.Currency);
    }

and the unit test:和单元测试:

    [Test]
    public void ToDecimal_Convert_String_To_Decimal()
    {
        Assert.AreEqual(1234M, "1234".ToDecimal());
        Assert.AreEqual(-1234.56M, "$(1,234.56)".ToDecimal());
        Assert.AreEqual(1234.56M, "$1,234.56".ToDecimal());
    }

Here is a method that most closely resembles the code you've provided这是一种与您提供的代码最相似的方法

public static decimal Parse(string input)
{
    return decimal.Parse(Regex.Replace(input, @"[^\d.]", ""));
}

Here is an option that will support negative numbers, and will stop if it finds a second period value, thus reducing the number of strings it returns that are not valid decimal values.这是一个支持负数的选项,如果它找到第二个句点值,它将停止,从而减少它返回的不是有效decimal值的字符串的数量。 It also has a few other modifications not seen in the OP to handle additional cases your current code doesn't.它还有一些在 OP 中看不到的其他修改来处理当前代码没有的其他情况。

public static decimal Parse(string input)
{
    return decimal.Parse(Regex.Match(input, @"-?\d{1,3}(,\d{3})*(\.\d+)?").Value);
}
decimal amount = decimal.Parse("$123,456.78",
NumberStyles.AllowCurrencySymbol |
NumberStyles.AllowThousands |
NumberStyles.AllowDecimalPoint);

works for all culture:适用于所有文化:

var d = decimal.Parse("$497.7", NumberStyles.Currency, CultureInfo.CreateSpecificCulture("us-US").NumberFormat);    

Console.WriteLine(d);
public static decimal ToDecimalFromStringDecimalOrMoneyFormattedDecimal(this string s)
{
    try
    {
        return decimal.Parse(s);
    }
    catch
    {
        var numberWithoutMoneyFormatting = Regex.Replace(s, @"[^\d.-]", "");
        return decimal.Parse(numberWithoutMoneyFormatting);
    }
}

[Test]
public void Test_ToDecimalFromStringDecimalOrMoneyFormattedDecimal()
{
    Assert.That("$ 500".ToDecimalFromStringDecimalOrMoneyFormattedDecimal() == (decimal)500);
    Assert.That("R -500".ToDecimalFromStringDecimalOrMoneyFormattedDecimal() == (decimal)-500);
    Assert.That("-$ 500".ToDecimalFromStringDecimalOrMoneyFormattedDecimal() == (decimal)-500);
    Assert.That("P 500.90".ToDecimalFromStringDecimalOrMoneyFormattedDecimal() == (decimal)500.9);
    Assert.That("$ -50 0,090,08.08".ToDecimalFromStringDecimalOrMoneyFormattedDecimal() == (decimal)-50009008.08);
}

We can try to use decimal.TryParse to cast the currency string value to a decimal number.我们可以尝试使用decimal.TryParse将货币字符串值转换为十进制数。

  • NumberStyles :use NumberStyles.Currency which indicates that all styles except AllowExponent and AllowHexSpecifier are used. NumberStyles :使用NumberStyles.Currency表示使用除AllowExponentAllowHexSpecifier之外的所有样式。 This is a composite number style.这是一种合数样式。
  • CultureInfo : we need to set the right culture of currency which align with your currency value. CultureInfo :我们需要设置正确的货币文化,与您的货币价值一致。

For this example, $20,000.00 is USA currency we can try to use English (USA) for that, on the other hand 20,000.00€ is euro currency we can try to use English (Ireland) that uses the euro currency.对于这个例子, $20,000.00是美国货币,我们可以尝试使用English (USA) ,另一方面20,000.00€是欧元货币,我们可以尝试使用使用欧元货币的English (Ireland)

decimal.TryParse("20,000.00€", NumberStyles.Currency ,CultureInfo.CreateSpecificCulture("en-IE"), out var euro);
Console.WriteLine(euro);
decimal.TryParse("$20,000.00", NumberStyles.Currency ,CultureInfo.CreateSpecificCulture("en-us"), out var dollar);
Console.WriteLine(dollar);

c# online c# 在线

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM