by Michael S. Kaplan, published on 2005/12/11 08:01 -05:00, original URI: http://blogs.msdn.com/b/michkap/archive/2005/12/11/502449.aspx
I have spoken previously about limitations that affect the support of percent formats in the .NET Framework's globalization classes, in the post entitled And you can't set all of the properties all of the time...
I thought I'd talk for a bit about the parsing support.
Make no mistake: the parsing support in the .NET Framework is very impressive, from a globalization standpoint.
Methods like Double.Parse can take both an IFormatProvider (which for numbers can be a NumberFormatInfo object) to provide the proper cultural settings to take what was once a particular type and has somehow found itself in string format, and a bitwise combination of NumberStyles flags:
Member name
Description
AllowCurrencySymbol
Indicates that the numeric string is parsed as currency if it contains a currency symbol; otherwise, it is parsed as a number. Valid currency symbols are determined by the CurrencySymbol property of NumberFormatInfo.
AllowDecimalPoint
Indicates that the numeric string can have a decimal point. Valid decimal point characters are determined by the NumberDecimalSeparator and CurrencyDecimalSeparator properties of NumberFormatInfo.
AllowExponent
Indicates that the numeric string can be in exponential notation.
AllowHexSpecifier
Indicates that the numeric string represents a hexadecimal value. Valid hexadecimal values include the numeric digits 0-9 and the hexadecimal digits A-F and a-f. Hexadecimal values can be left-padded with zeros. Strings parsed using this style are not permitted to be prefixed with "0x".
AllowLeadingSign
Indicates that the numeric string can have a leading sign. Valid leading sign characters are determined by the PositiveSign and NegativeSign properties of NumberFormatInfo.
AllowLeadingWhite
Indicates that a leading white-space character must be ignored during parsing. Valid white-space characters have the Unicode values U+0009, U+000A, U+000B, U+000C, U+000D, and U+0020.
AllowParentheses
Indicates that the numeric string can have one pair of parentheses enclosing the number.
AllowThousands
Indicates that the numeric string can have group separators; for example, separating the hundreds from the thousands. Valid group separator characters are determined by the NumberGroupSeparator and CurrencyGroupSeparator properties of NumberFormatInfo and the number of digits in each group is determined by the NumberGroupSizes and CurrencyGroupSizes properties of NumberFormatInfo.
AllowTrailingSign
Indicates that the numeric string can have a trailing sign. Valid trailing sign characters are determined by the PositiveSign and NegativeSign properties of NumberFormatInfo.
AllowTrailingWhite
Indicates that trailing white-space character must be ignored during parsing. Valid white-space characters have the Unicode values U+0009, U+000A, U+000B, U+000C, U+000D, and U+0020.
Any
Indicates that all styles, except AllowHexSpecifier, are used. This is a composite number style.
Currency
Indicates that all styles, except AllowExponent and AllowHexSpecifier, are used. This is a composite number style.
Float
Indicates that the AllowLeadingWhite, AllowTrailingWhite, AllowLeadingSign, AllowDecimalPoint, and AllowExponent styles are used. This is a composite number style.
HexNumber
Indicates that the AllowLeadingWhite, AllowTrailingWhite, and AllowHexSpecifier styles are used. This is a composite number style.
Integer
Indicates that the AllowLeadingWhite, AllowTrailingWhite, and AllowLeadingSign styles are used. This is a composite number style.
None
Indicates that none of the bit styles are allowed.
Number
Indicates that the AllowLeadingWhite, AllowTrailingWhite, AllowLeadingSign, AllowTrailingSign, AllowDecimalPoint, and AllowThousands styles are used. This is a composite number style.
This is obviously a pretty comprehensive representation of the various kinds of things that you can do with formatting, although it is missing one item.
Percentages.
What that means is that currently in the .NET Framework cannot roundtrip values through percentage formats.
Of course even getting values into percantages via formatting is more difficult than it is for numbers and currency values.
A hint as to why can be found if you look at the standard formatting characters supported in NumberFormatInfo:
Format Character Description and Associated Properties c, C Currency format. CurrencyNegativePattern, CurrencyPositivePattern, CurrencySymbol, CurrencyGroupSizes, CurrencyGroupSeparator, CurrencyDecimalDigits, CurrencyDecimalSeparator. d, D Decimal format. e, E Scientific (exponential) format. f, F Fixed-point format. g, G General format. n, N Number format. NumberNegativePattern, NumberGroupSizes, NumberGroupSeparator, NumberDecimalDigits, NumberDecimalSeparator. r, R Roundtrip format, which ensures that numbers converted to strings will have the same value when they are converted back to numbers. x, X Hexadecimal format.
Notice what is not there along with the Currency and Number formats -- the Percentage format. Something that would take PercentNegativePattern, PercentPositivePattern, PercentSymbol, PercentGroupSizes, PercentGroupSeparator, PercentDecimalDigits, and PercentDecimalSeparator into account.
Now one thing that is possible is creating your own class that supports IFormatProvider.
This means that one could perhaps write all the code between IFormatProvider and ICustomFormatter to do this work without waiting for it to be added to the .NET Framework.
Though I honestly do not know if this would work or not, since it is unclear (to me at least) how much of the parsing code relies on the IFormatProvider....
Probably worth trying some weekend, though. I'll report back if I find out anything interesting....
This post brought to you by "%" (U+ff05, a.k.a. FULLWIDTH PERCENT SIGN)
referenced by