Problem
A friend from Venezuela wrote me with the following problem (summarized): I receive some files from different countries that have some amounts (in string), the problem is that each region has its way of formatting the numerical quantities. When I read a file with C#, nothing tells me the region format of the amounts. I will receive amounts like the following:
- 123,456.78
- 123.456,78
- 123,456 (no decimals)
How to make a function that takes a string like the previous ones, and returns its representation in decimal?
My Solution
Given the fact that we do not know in advance the regional culture of the amounts of the file to read, we need a function that accepts an arbitrary amount like the previous ones and returns the amount as a decimal.
My solution was to remove all the separators, periods and commas, and to parse that number. Then, if the original amount had decimal numbers, we divided the result by 100. Here is the code:
public static decimal ParseDecimalIgnoringCulture(string amount) { var hasDecimals = HasDecimals(amount); var amountWithoutSeparators = amount.Replace(",", "").Replace(".", ""); var amountDecimal = decimal.Parse(amountWithoutSeparators); var divisionFactor = hasDecimals ? 100 : 1; return amountDecimal / divisionFactor; } public static bool HasDecimals(string amount) { var lastIndexOfComma = amount.LastIndexOf(','); var lastIndexOfPoint = amount.LastIndexOf('.'); if (lastIndexOfComma == -1 && lastIndexOfPoint == -1) { return false; } var lastIndexOfSeparator = lastIndexOfComma > lastIndexOfPoint ? lastIndexOfComma : lastIndexOfPoint; return amount.Length - lastIndexOfSeparator == 3; }
Note: The previous code assumes that, if there are amounts with decimals, the number of decimal digits will be equal to 2.
Thanks!