我想将Text输入中的字符串解析为decimal。该值代表货币值。
目前我得到了这个解决方案:
private Decimal CastToDecimal(string value)
{
Decimal result;
var valid = Decimal.TryParse(value, NumberStyles.Currency, null, out result);
return valid ? result : -1;
}
到目前为止,除了可能的文化差异外,这种方法效果很好。我是德国人,我希望大多数用户进入德国风格的标点。但有可能有人使用“。”而不是“,”,转换将失败。
“123,45€”=> 123.45
“123.456,78€”=> 123456.78
“123.45€”=> 12345 < - 我希望结果是123.45
有没有办法自动检测使用的文化为十进制值?如果您使用德语或英语标点符号无关紧要,您仍会得到相同的结果吗?
更新
感谢您的帮助,我创建了一种方法,可以满足我的需求(我认为)。
private static Decimal CastToDecimal(string value)
{
Decimal resultDe;
Decimal resultEn;
var style = NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands;
var cultureDe = CultureInfo.CreateSpecificCulture("de-DE");
var cultureEn = CultureInfo.CreateSpecificCulture("en-GB");
var deValid = Decimal.TryParse(value, style, cultureDe, out resultDe);
var enValid = Decimal.TryParse(value, style, cultureEn, out resultEn);
var minVal = Math.Min(resultDe, resultEn);
var maxVal = Math.Max(resultDe, resultEn);
if (!deValid)
return resultEn;
if (!enValid)
return resultDe;
return BitConverter.GetBytes(decimal.GetBits(minVal)[3])[2] > 2 ? maxVal : minVal;
}
此代码......
Console.WriteLine(CastToDecimal("123,45"));
Console.WriteLine(CastToDecimal("123.45"));
Console.WriteLine(CastToDecimal("123,450"));
Console.WriteLine(CastToDecimal("123.450"));
Console.WriteLine(CastToDecimal("123.123,45"));
Console.WriteLine(CastToDecimal("123,123.45"));
返回:
123,45
123,45
123450
123450
123123,45
123123,45
答案 0 :(得分:1)
前段时间我遇到了同样的问题。我的解决方案是用Java编写自己的解析器。该算法首先清理字符串。简要说明如下:
7是唯一一个像chiastic-security已经说过的问题。在这里,您只能考虑概念环境。所有其他情况都是安全的。
玩得开心
答案 1 :(得分:1)
http://msdn.microsoft.com/en-us/library/3s27fasw%28v=vs.110%29.aspx处的解决方案 其中包括设置NumberStyle可能会有所帮助。
...
value = "1.345,978";
style = NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands;
culture = CultureInfo.CreateSpecificCulture("es-ES");
if (Double.TryParse(value, style, culture, out number))
Console.WriteLine("Converted '{0}' to {1}.", value, number);
else
Console.WriteLine("Unable to convert '{0}'.", value);
// Displays:
// Converted '1.345,978' to 1345.978.
value = "1 345,978";
if (Double.TryParse(value, style, culture, out number))
Console.WriteLine("Converted '{0}' to {1}.", value, number);
else
Console.WriteLine("Unable to convert '{0}'.", value);
...
答案 2 :(得分:0)
这是不可能做到的,仅仅因为有两种不同文化中有意义的字符串,但意味着不同的东西。例如:
123.456
123,456
第一个在英国略超过123,但在德国有123456;第二个是英国的123456,但在法国有一个超过123个。
答案 3 :(得分:0)
唯一的解决方案是在输入上添加验证,如果是网页则为用户提供示例,然后根据用户的文化找到获取输入的方法。我建议你不要尝试做你正在尝试的事情,因为有些文化会互相矛盾,例如货币;
美国/澳大利亚/许多其他人使用以下格式
45,999.95
其中,是千分隔符和。是小数点分隔符
而在某些欧洲国家
45.999,95
表示与上述相同但千位分隔符。并用作小数分隔符。
现在问题是无法保证用户同时使用两个分隔符,您的系统可能会假设千位分隔符为十进制,依此类推。
如果您真的不想打扰用户,请为主要货币和次要货币创建单独的输入字段。
所以最好不去那里。我相信这可能会有所帮助。快乐编码:)
<强>更新强>:
同样的情况是日期格式,例如在美国格式的月份是第一天然后是一天,而在澳大利亚的日子是第一个然后是月份,现在02/01/2015
输入将意味着不同的系统不能告诉用户的意图。