views:

1537

answers:

2

.NET supports two types of string formatting.

I'm in a situation where existing configuration data has #,##0 style formatting. A new feature requires formatting to the same output, but the API needed for this feature only accepts formatting of type {0:n2}.

Does anyone know of a means to convert between these two representations for numeric types? DateTime can be ignored.

EDIT I've learned that:

+1  A: 

No, you can't.

From your link to the MSDN articles about standard format strings, you'll find:

The actual negative number pattern, number group size, thousand separator, and decimal separator are specified by the current NumberFormatInfo object.

So the standard formatting specifiers will vary depending on which culture the program is running under.

Since your custom formating specifies exactly how the number is going to look, whatever the culture the program is running under. Its allways gonna look the same.

The culture the program is running under isn't known during compile time, it's a runtime property.

So the answer is: No, you can't map automatically, because there isn't a one-to-one consistent mapping.

Arjan Einbu
@Arjan, dang. I wasn't really thinking outside my locale as it's an in-house app, but thanks for explaining this. The purpose of these different formats is clear to me now. Great answer.
Drew Noakes
A: 

HACK ALERT!!!

As Arjan pointed out in his excellent answer what I want to do isn't possible in a bullet proof fashion across all locales (Thanks Arjan).

For my purposes, I know I'm only dealing with numbers and the major thing I'm concerned with is having the same number of decimal places. So here's my hack.

private static string ConvertCustomToStandardFormat(string customFormatString)
{
    if (customFormatString == null || customFormatString.Trim().Length == 0)
        return null;

    // Percentages do not need decimal places
    if (customFormatString.EndsWith("%"))
        return "{0:P0}";

    int decimalPlaces = 0;

    int dpIndex = customFormatString.LastIndexOf('.');
    if (dpIndex != -1)
    {
        for (int i = dpIndex; i < customFormatString.Length; i++)
        {
            if (customFormatString[i] == '#' || customFormatString[i] == '0')
                decimalPlaces++;
        }
    }

    // Use system formatting for numbers, but stipulate the number of decimal places
    return "{0:n" + decimalPlaces + "}";
}
Drew Noakes