在.NET中使用十进制类型时出现的问题
我在使用.NET和十进制类型时遇到了一个奇怪的问题。我的web应用程序使用以下全球化设置:在.NET中使用十进制类型时出现的问题,.net,globalization,.net,Globalization,我在使用.NET和十进制类型时遇到了一个奇怪的问题。我的web应用程序使用以下全球化设置: <globalization culture="auto" enableClientBasedCulture="true"/> 考虑到以下情况:十进制值123在英镑中变为123英镑,欧元为123 00英镑(注:逗号)。当我想从小数点后的123,00欧元(EUR)再次回到英镑时,我遇到的问题就出现了,因为它变成了123000英镑——这是一个巨大的问题 在这个场景中,我的应用程序根据检测到的
<globalization culture="auto" enableClientBasedCulture="true"/>
考虑到以下情况:十进制值123在英镑中变为123英镑,欧元为123 00英镑(注:逗号)。当我想从小数点后的123,00欧元(EUR)再次回到英镑时,我遇到的问题就出现了,因为它变成了123000英镑——这是一个巨大的问题
在这个场景中,我的应用程序根据检测到的区域性查询一个查找表,并以该货币显示价格。只有当用户做出选择并且准备好将数据发送到我们的支付网关(将123,00欧元转换为123000欧元)时,问题才会出现
有什么办法可以克服这个问题吗?也许这对你有帮助
NumberFormatInfo ni = new NumberFormatInfo();
ni.NumberDecimalSeparator = '.';
用法,即
Double.Parse(MyString, ni)
-雷特
不知道有什么更好的方法来检测格式,但是看看这个
static void Main(string[] args)
{
// German Format (EUR)
CultureInfo ci_de = new CultureInfo("de-DE");
// English Format (GBP)
CultureInfo ci_gb = new CultureInfo("en-GB");
string test_de = "1.234.567.890,12";
string test_en = "1,234,567,890.12";
double result_de = 0.0;
double result_en = 0.0;
try
{
result_de = Double.Parse(test_en, ci_de.NumberFormat);
}
catch (FormatException ex)
{
Console.WriteLine("Number isn't a german format " + ex.InnerException);
}
try
{
result_en = Double.Parse(test_en, ci_gb.NumberFormat);
}
catch (FormatException ex)
{
Console.WriteLine("Number isn't a english format " + ex.InnerException);
}
Console.WriteLine(result_de.ToString());
Console.WriteLine(result_en.ToString());
Console.ReadLine();
}
decimal数据类型基本上只保存一个数字——没有隐式应用于它的格式。数字的值不会因为以不同的格式显示而改变
很可能,您可能遇到的问题是,当您从网页接收作为字符串的输入时,您对其进行了错误的解析。rAyt提供了一个良好的开端,但如果您使用各种区域性,则可能很难自动检测十进制数是哪个区域性。为了确保您总是知道,最好围绕包含区域性的decimal创建一个简单的包装器类型。您需要更新数据存储,以同时存储区域性代码(即en US),以便在重建数据时不会“忘记”数据保存为什么区域性。您拥有的任何实体都将使用decimal包装类型,而不是直接使用decimal,并且该类型可以有一个重写的ToString方法,以正确的格式自动呈现:
public struct CulturedDecimal
{
public decimal Value;
public CultureInfo Culture;
public override ToString()
{
return Value.ToString(Culture);
}
}
public class SomeEntity
{
public int ID { get; set; }
public CulturedDecimal MonetaryValue { get; set; } // Was 'decimal' before
}
感谢所有提供经验和建议的人 实现用于保存自己的十进制值的自定义类型/结构并不是我真正想要的,也不会真正为我提供所需的功能(我已经可以以适当的本地货币/格式显示十进制值,我只是无法在需要时将其转换回英国格式) 问题在于web配置中的这一行:
<globalization culture="auto" enableClientBasedCulture="true"/>
在这个设置中,我的所有十进制值(内部)始终被视为en GB小数,因此采用我需要的格式。换句话说,我的应用程序不需要灵活地更改应用于整个当前线程的设置;恰恰相反:我只关心不同格式的值。您好,谢谢您的回复。我尝试了ni.NumberDecimalDigits=“.”(vb.net),但这会产生一个格式异常。你是说ni.CurrencyDecimalSeparator=“.”?请包括整个代码。这很有帮助。是的,您也可以使用CurrencyDecimalSeparator。但如果从欧元(100,00)转换为英镑“100.00”,则需要将其设置为CurrencyDecimalSeparator=”,好的,如果我明确知道我正在从欧元转换为英镑,则可以这样做,但情况并非总是如此。那么,我如何检测(纯从十进制值)要使用的设置呢?谢谢你,吉姆,我认为你是绝对正确的。。。我在调试器中确认,无论语言环境如何,十进制变量的值始终表示为“123.00”,而不是“123,00”。那么,我的问题一定是发生在转换为字符串的过程中的其他地方——正如您所说的那样。感谢您迄今为止的帮助,各位,尽管如此,我仍然没有取得任何进展。我会继续试验并发布进展。在这方面仍然没有进展。我需要根据用户文化显示格式化的数字,但我必须能够以en GB格式存储数字,即“123.00”=£123.00,€123,00=123.00,而不是“123000”,这是NumberInfo类将欧元值123,00格式化为en GB时的值。您仍然需要理解十进制数字(如中所述,您在程序中使用的变量与.Net应用程序使用的文化无关,它只是一个数字)。当您开始尝试将字符串转换为十进制,或将十进制转换为字符串时(即打印出来时)这种区域性介入并产生影响。这意味着,如果您希望.Net处理输出的区域性,您可以像以前一样简单地执行操作-但是当从外部系统以字符串形式读入数字时,您需要知道它以何种格式进入您的系统,并将其视为一种格式。此外,如果我没有弄错的话,请使用fr locale使用空格表示小数点,逗号表示千位分隔符,这就是为什么123,00计算为123000。区域设置是一件棘手的事情,相信我,我知道你的痛苦。我也用多个区域设置处理一个系统,我用以下方法处理它。1.网站上的所有用户输入都在输入区域设置中被接受(比方说fr)-并在同一地区打印(fr)。当接受来自其他地方的输入时,它是以不变量文化格式接受的。Hi Kastermester,感谢您的评论-非常感谢您的反馈。我确实理解十进制类型不是“特定文化”,这就是为什么我最初对我面前的问题感到困惑的原因。因为这是不可能的(在我们的实现中)要接受任何区域性中的输入(以及存储该区域性并在以后正确设置其格式),我真正需要做的就是确保一个特定的.ToString()十进制的表示形式始终是“en GB”,但仍然尊重并在用户所在区域的站点的其他区域显示十进制值。现在这个问题已经解决了,我将做更多的实验来了解更多关于这个主题的内容。我很想知道为什么在我的初始测试(伪代码)“123.00D”。ToString(“c”,“fr-fr]”)生成FormatException,而“123,00D”.ToStr
NumberFormatInfo ni = Globalization.CultureInfo.GetCultureInfo("fr-FR").NumberFormat;
Decimal.ToString("c", ni);