C#: Parsing decimals with distinct region formats: 123,456.78 y 123.456,78

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!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s