在 .NET 中解析文化特定的 Decimal 和 DateTime 值

Parsing Cultural Specific Decimal and DateTime values in .NET

我有一个 ASP.NET MVC 应用程序,它必须支持英语和德语。在我的一个观点中,用户正在输入一个十进制值和一个 date/time 值。

// Get the price
string price = "1.23";
decimal priceValue = 0;
var allowedStyles = (NumberStyles.AllowDecimalPoint & NumberStyles.AllowThousands);
if (Decimal.TryParse(price, allowedStyles, CultureInfo.InvariantCulture, out priceValue))
{
  model.Price = priceValue;
}
else
  errors.Add("Please enter a valid price.");

// Parse the date
string date = "03/23/2015";
if (String.IsNullOrWhiteSpace(date) == false)
{
  DateTime dateValue = DateTime.MinValue;
  if (DateTime.TryParse(saleDate, out dateValue))
  {
    model.Date = dateValue;
  }
  else
    errors.Add("Please enter a valid date.");
}

当上面的代码在英语文化中运行时,Decimal.TryParse 行 returns false。当代码在德国文化中运行时,Decimal.TryParseDateTime.TryParse 行都 return false。我究竟做错了什么?如何跨文化解析 Decimal 和 DateTime 值?

你不应该为此使用 InvariantCulture。您应该一次使用一种文化进行解析,如果失败则尝试另一种文化。

When the above code runs in the English culture, the Decimal.TryParse line returns false

因为您在 & operator and NumberStyles.AllowDecimalPoint & NumberStyles.AllowThousands generates NumberStyles.None which indicates no style for your element. From documentation;

中使用按位与

Indicates that no style elements, such as leading or trailing white space, thousands separators, or a decimal separator, can be present in the parsed string. The string to be parsed must consist of integral decimal digits only.

如果您将 & 更改为 | 您的 Decimal.TryParse returns true.

When the code runs in the German culture, both the Decimal.TryParse and DateTime.TryParse lines return false.

Decimal.TryParse 方法相同。 但是de-DE 文化有 , 而不是 . 作为 NumberDecimalSeparator. But it has . as a NumberGroupSeparator 这就是为什么它将你的 1.23 值解析为123。它认为这是千位分隔符,而不是小数点分隔符。

对于你的 DateTime.TryParse 方法,因为你没有告诉我们 saleDate 到底是什么,看起来它不是 standard date and time format for your CurrentCulture,这就是为什么 returns false.

如果你的意思是 date 而不是 saleDate,那意味着 MM/dd/yyyy 不是你的 CurrentCulture 的标准日期和时间格式,也不是 de-DE 文化。

你可以使用DateTime.TryParseExact or DateTime.ParseExact (preferable) method with a culture that has / as a DateSeparator like InvariantCulture喜欢;

string date = "03/23/2015";
DateTime dt;
if(DateTime.TryParseExact(date, "MM/dd/yyyy", CultureInfo.InvariantCulture,
                          DateTimeStyles.None, out dt))
{
    model.Date = dateValue;
}