如何使decimal.Parse接受多种文化

时间:2012-08-20 23:37:11

标签: c# windows-phone-7

我需要在我的应用中接受3种十进制数据格式:

  • 123456,78 => 123456.78
  • 123,456.78 => 123456.78
  • 123456.78 => 123456.78

我不能假设在特定情况下会使用一种格式。我需要的是从字符串中获取十进制值,无论它以何种格式给出。

有没有聪明的方法来做到这一点?

我正在尝试使用

var culture = CultureInfo.CreateSpecificCulture("en-US");

但这似乎不适用于wp7。

到目前为止,我已经这样做了:

public static class Extensions
{

    public static decimal toDecimal(this string s)
    {
        decimal res;

        int comasCount=0;
        int periodsCount=0;

        foreach (var c in s)
        {
            if (c == ',')
                comasCount++;
            else if (c == '.')
                periodsCount++;
        }

        if (periodsCount > 1)
            throw new FormatException();
        else if(periodsCount==0 && comasCount > 1)
            throw new FormatException();

        if(comasCount==1)
        {
            // pl-PL
            //parse here
        }else
        {
            //en-US
            //parse here
        }

        return res;
    }
}

3 个答案:

答案 0 :(得分:3)

尝试使用var culture = new CultureInfo("en-US");来创建文化。将该文化传递给decimal.Parsedecimal.TryParse将适当地解析每种文化的文本。

现在,请记住,每种文化都可以在不失败的情况下解析文本,但不能按照原始文化的方式对其进行解析。例如decimal.TryParse("1000,314", NumberStyles.Number, new CultureInfo("en-US"), out result)将获得成功并且将产生1000314m,而不是1000.314m。而decimal.TryParse("1000,314", NumberStyles.Number, new CultureInfo("fr-FR"), out result)将导致1000.314米。

答案 1 :(得分:1)

您可以尝试这样的事情:

public static decimal ParseDecimalNumber( string s , string groupSeparators , string decimalPoints )
{
  NumberFormatInfo nfi   = (NumberFormatInfo) CultureInfo.InvariantCulture.NumberFormat.Clone() ;
  NumberStyles     style = NumberStyles.AllowLeadingWhite
                         | NumberStyles.AllowLeadingSign
                         | NumberStyles.AllowThousands
                         | NumberStyles.AllowDecimalPoint
                         | NumberStyles.AllowTrailingSign
                         | NumberStyles.AllowTrailingWhite
                         ;
  decimal          value ;
  bool             parsed = false ;

  for ( int i = 0 ; !parsed && i < groupSeparators.Length ; ++i )
  {

    nfi.NumberGroupSeparator = groupSeparators.Substring(i,1) ;

    for ( int j = 0 ; !parsed && j < decimalPoints.Length ; ++j )
    {
      if ( groupSeparators[i] == decimalPoints[j] ) continue ; // skip when group and decimal separator are identical

      nfi.NumberDecimalSeparator = decimalPoints.Substring(j,1) ;

      parsed = Decimal.TryParse( s , style , nfi , out value ) ;

    }
  }

  if ( !parsed ) throw new ArgumentOutOfRangeException("s") ;

  return value ;

}

用法很简单:

string groupSeparators = "., " ;
string decimalPoints   = ".,"  ;
Decimal value = ParseDecimalNumber( someStringContainingANumericLiteral , groupSeparators , decimalPoints ) ;

答案 2 :(得分:0)

TryParse的不同NumberStylesIFormatProvider设置为null的三次调用都应该这样做。