12

I am getting data from a csv file and parsing it to my application. In my csv file I have a column price whose value I use as of course the price of an item in my project.

However, the price in the csv file does not contain trailing 0s, For example, if the price of and item is $5.00, the csv file has it as $5, if the price is $9.60, the csv has it as $9.6. Other prices such as $9.56 are fine though.

This is how I retrieve the price from the csv file:

 Price = string.IsNullOrEmpty(columns[3].Trim()) ?
     null : (decimal?)decimal.Parse(columns[3]), 

In my class Price is set as public decimal? Price { get; set; }.

How do I format what is returned to fix this problem?

Price = String.Format("Price: {0:C}", 
     string.IsNullOrEmpty(columns[3].Trim()) ? 
        null : (decimal?)decimal.Parse(columns[3]));

I tried the above but didn't work.

How do I fix it so that values in the csv as $5.9 are formatted to $5.90.

EDIT:

Tried:

Price=decimal.Round(string.IsNullOrEmpty(columns[3].Trim()) ? 
    null : 
    (decimal?)decimal.Parse(columns[3]), 2, MidpointRounding.AwayFromZero);

Not sure if I did that right?

Also, I'm not certain how I can use the below option in my code:

decimalVar.ToString ("#.##");

Also tried:

 Price = string.IsNullOrEmpty(columns[3].Trim()) ? 
      null : (decimal?)decimal.Parse(columns[3], NumberStyles.Currency)

But still doesn't work.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
user3237078
  • 141
  • 1
  • 1
  • 6

3 Answers3

29

You are looking for "0:C2" see Standard Numeric Format Strings

Precision specifier: Number of decimal digits

Sample:

 String.Format("{0:C2}", 5d); //results in $5.00
 String.Format("{0:C2}", 5.9d); //results in $5.90
 String.Format("{0:C2}", 5.123d); //results in $5.12
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • Ok, but Price is set as as type decimal in my class. Also I can't specify the value for each, it is retired from column[3] from my csv. – user3237078 Jan 30 '14 at 19:27
  • This answer is fine. You are still confusing the fact of a number with the textual display. – DonBoitnott Jan 30 '14 at 19:58
  • I don't understand why this answer has an up-vote when my answer achieves the same result, while also explaining the parsing required. Just a bit confused... – Lukazoid Jan 30 '14 at 22:34
  • Ok then would this be the correct means `Price = string.IsNullOrEmpty(columns[3].Trim()) ? null : (decimal?)decimal.Parse(String.Format("{0:C2}", columns[3]d)), ` not sure how to integrate your answer with my question code – user3237078 Jan 31 '14 at 01:20
  • @user3237078 - unfortunately your code is hard to read/modify, so you'd have to do it yourself - sorry. If you stop trying to do all code in single statement it will make writing code easier. There is no extra cost for creating local variables separate parsing data from formatting - so make separete variables for each step: read string from CSV, convert into decimal, format into string when needed. – Alexei Levenkov Jan 31 '14 at 01:25
  • This worked fine when I used in in the app layer not the service layer. – user3237078 Jan 31 '14 at 01:26
  • You're looking for "{0:C2}" not "0:C2". The later will print the literal string C2 while replacing the 0 with the first digit of the value. – Triynko Aug 29 '16 at 17:26
5

This answer is going to assume that your local currency symbol is $.

Use Decimal.Parse(String, NumberStyles) to parse the string, i.e:

string priceFromCsv = "$5";
var priceAsDecimal = Decimal.Parse(priceFromCsv, NumberStyles.Currency);

Then use Decimal.ToString(String) with the format "C" to get back to a fully formed currency, i.e.

priceAsDecimal.ToString("C");

This will give you the fully formed currency with the correct number of decimal places.

Lukazoid
  • 19,016
  • 3
  • 62
  • 85
  • When I tried this ` Price = string.IsNullOrEmpty(columns[3].Trim()) ? null : (double?)Decimal.Parse(columns[3], NumberStyles.Currency),` I get an error "The name "NumberStyles" does not exist in the current context" – user3237078 Jan 30 '14 at 18:54
  • Never mind that, just fixed that error by adding the reference – user3237078 Jan 30 '14 at 18:56
  • Still not working. I have been trying to integrate this with `string.IsNullOrEmpty(columns[3].Trim()) ? null : (decimal?)decimal.Parse(columns[3])` but I can;t get it do work – user3237078 Jan 30 '14 at 19:06
  • Do you want empty strings to be formatted to "$0.00" or result in a null `string`? – Lukazoid Jan 30 '14 at 22:36
  • *I don't understand why this answer has an up-vote when my answer achieves the same result, while also explaining the parsing required*... I don't understand why people keep asking the same questions without searching first... that's just how this place works sometimes. ;) – Sheridan May 20 '14 at 15:31
1

decimals don't have a "format" - they are just a number. It looks like you're trying to "assign" a format to the Price column which you can't do. Based on your first code sample it seems that you're able to parse the CSV input to a decimal just fine.

You get to choose the format when you display the value, which you haven't indicated where that happens. In an app? a report? another CSV?

D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • I get the data from the csv in a web service, the code above is used in my web service. This data in the web service is used in a windows 8 app. It returns as decimal fine, all I'm trying to do is fix the rounding off, so that a value that is $5.9, would be formatted in my web service to be used in my app as $5.90 – user3237078 Jan 30 '14 at 19:22
  • You do that when you display the value _in the app_, not when you import the data. – D Stanley Jan 30 '14 at 19:25
  • So this can't be done on the web service? But I have formatted other csv items to be used in my app – user3237078 Jan 30 '14 at 19:28
  • It could if the type was `string` instead of `decimal`. I would still contend that _formatting_ belongs in the UI layer, not the service layer. – D Stanley Jan 30 '14 at 20:24
  • I actually used the formatting in the app layer and it worked well, not really what I wanted but it works. I would like to vote up your answer but I don't have enough rep. – user3237078 Jan 31 '14 at 01:27