Yuri Morales
Yuri Morales

Reputation: 2498

Convert fixed length number to decimal .NET C#

I have a import txt file with number in this format:

00000000003000
00000000009500
00000000003000
00000000002000
00000000000500-
00000000001500-
00000000003000-
00000000003000-
00000000009500-

This is the number which last 2 chars are the decimals. (minus sign if negative value) For example:

00000000003000 = 30.00
00000000000500- = -5.00

Is there a function to convert this string to decimal and save my time writing one?

Thanks.

Upvotes: 1

Views: 1167

Answers (3)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186688

Try this:

 String source = "00000000001500-";

 Decimal result = Decimal.Parse(source, 
   NumberStyles.Any, // NumberStyles.Any includes trailing signs
   CultureInfo.InvariantCulture) / 100.0M;

If you want (for some fields, values) four decimal places just change 100.0M to 10000.0M for these fields:

 Decimal result4 = Decimal.Parse(source, 
   NumberStyles.Any, // NumberStyles.Any includes trailing signs
   CultureInfo.InvariantCulture) / 10000.0M;

Upvotes: 9

Tim Schmelter
Tim Schmelter

Reputation: 460108

You can use decimal.Parse with a custom format provider with the proper NumberFormatInfo.NumberNegativePatternthat appends the minus => formatProvider.NumberNegativePattern = 3;:

var formatProvider = (NumberFormatInfo)NumberFormatInfo.InvariantInfo.Clone();
formatProvider.NumberNegativePattern = 3;
var numbers = File.ReadLines(yourFilePath)
    .Select(l => l.TryGetDecimal(formatProvider))
    .Where(n => n.HasValue)
    .Select(d => d.Value / 100.0M);

Used this extension to parse the string to decimal in a LINQ query:

public static decimal? TryGetDecimal(this string item, IFormatProvider formatProvider = null, NumberStyles nStyles = NumberStyles.Any)
{
    if (formatProvider == null) formatProvider = NumberFormatInfo.CurrentInfo;
    decimal d = 0m;
    bool success = decimal.TryParse(item, nStyles, formatProvider, out d);
    if (success)
        return d;
    else
        return null;
}

If you want the sum of all your decimals you can use Enumerable.Sum:

decimal sum = numbers.Sum(); // 0

Upvotes: 1

Luaan
Luaan

Reputation: 63732

Nothing that would target your exact scenario specifically - the trailing - being quite uncommon in particular.

I'd just use something like this:

public static decimal Parse(string val)
{
  return (val.EndsWith("-") ? -1M : 1M) 
         * decimal.Parse
           (
             val.Substring(0, 12) 
             + "." + val.Substring(12, 2), 
             CultureInfo.InvariantCulture
           );
}

Or, using NumberStyles.AllowTrailingSign:

public static decimal Parse(string val)
{
  return 
    decimal.Parse
      (
        val.Substring(0, 12) 
        + "." + val.Substring(12), 
        NumberStyles.AllowTrailingSign | NumberStyles.AllowDecimalPoint, 
        CultureInfo.InvariantCulture
      );
}

Upvotes: 3

Related Questions