C# Decimal Formatting Query - c#

I am trying to format a decimal so that it will get displayed as so:
14.5 should get displayed as "14.50"
14.50 should get displayed as "14.50"
14.05 should get displayed as "14.05"
14.00 should get displayed as "14"
Is the possible with a single String Format, i.e. not using conditional formatting?
I've tried "0.##" (doesn't satisfy the first example) and "0.00" (doesn't satisfy the last example).
Thanks.

Yes. You can use the "G" format specifier. For samples, see String.Format's documentation.
For example:
decimal value = 14.05m;
string result = String.Format("{0:G}", value); // "14.05"
value = 14m;
result = String.Format("{0:G}", value); // "14"

You could use something like:
FormatNumber(VariableToBeFormatted, 2).Replace(".00", String.Empty)

I don't think you'll be able to do that without some sort of conditional formatting, because you want the formatting to do different things in different cases.
If you'd settle for 14.5 instead of 14.50, then you'd be OK with the 0.## syntax, but I can't think of a way to do it.

Follow Reed's answer and add a check after that:
resultArray = result.Split('.');
if (resultArray.Length > 1 && resultArray[1].Length != 2)
result = String.Format("{0.00}", value);
Not exactly elegant, but will get you the result you desire.
This is assuming the person saying it doesn't apply to 14.5 is correct in the comments.

Related

Formatting a string to display custom decimal values

I'm trying to format some doubles properly so that they will display properly for my uses (I'm building a statement in Devexpress, so I'm working with a lot of numbers).
Here are the basic formatting rules I'd like to have happen:
1000.2 -> 1,000.20
1000 -> 1,000
1000.22 -> 1,000.22
Is this possible using string formatting in C#? I've tried the following, but not been able to achieve my goal:
#,#.## - gives me 1,000.2 for the first value
#,#.#0 - gives me 1,000.00 for the second value
#,#.00 - gives me 1,000.00 for the second value
EDIT: Some more information. DevExpress gives me the ability to use string formatting to set up the values after they've been bound to the report. We're doing it at report time (and not at calculation time in the behind the scenes code) because we use the Sum function within the tables that DevExpress offers us. The reason we do THAT is so that we can minimize calls to our database by doing one large pull of data, then using that table over and over again in the statement and filtering based on the restrictions within.
EDIT EDIT:
Based on the feedback I've receieved here in the comments, it's not possible to perform the formatting I'd like to do with only providing a string format; I would need to insert some code either when I provide the data to the report (and then remove any and all formatting from the report) and perform all summing functions at the code level (to ensure that the sum values have the expected decimal places), or I would need to accept .00 at the end of, for example, some amount of yen (100 JPY would never be represented as 100.00 JPY, as an example).
This is a bit of an esoteric case, but it's good to know!
You can use string formatting coupled to a simple if condition. To shorten it's use, you can also make it an Extension method. It can look like this :
public static string FormatConditionnaly(this double input)
{
return input % 1 == 0 ? input.ToString("#,0") : input.ToString("#,0.00");
}
Basically, if you number does not contain any decimals (the % 1 == 0 check), you format it without decimals. If it fails the check, you add the two zeroes.
It is used like that :
const double flatNumber = 1000;
string result1 = flatNumber.FormatConditionnaly(); //1,000
const double numberWithDecimals = 1000.5;
string result2 = numberWithDecimals.FormatConditionnaly(); //1,000,50
Bit of a hack but you can give this a try:
s = String.Format("{0:N2}", 1000).Replace(".00", "");
Use the "N" format specifier as the format string when you call ToString(); See here
For example:
int intValue = 123456789;
Console.WriteLine(intValue.ToString("N2",
CultureInfo.InvariantCulture).Replace(".00", "");
You can customize group sizes etc. as needed.
Why don't you format the values before binding to DevExpress control using plain old C# (Assuming you are doing a bind, as you have not given sufficient details.)
In c# the Math.Round() should do the trick.
Example Math.Round(doubleValue,2) where the second parameter is the number of decimal places.
EDIT:
#,##0.00
I Do not have DevExpress controls to test my solution but I did find http://documentation.devexpress.com/#windowsforms/CustomDocument1498 online (not sure if you see it already).
It seems you can use the Number or Currency masks.
Also take a look at the Zero Placeholder under the custom section. based on the description, '0' is filled where the user has not supplied a value.
example: 123.4 --> 123.40
If the string that you're trying to format is in an XRTableCell of an XtraReport instance, you can handle the BeforePrint event on that cell to format its text. This event is triggered anytime that the report is rendered. Call GetCurrentColumnValue to retrieve the value that you want to format, use any of the code methods from the previous answers that will work for you, and then set that cell's text with your formatted string. Using #dweeberly's answer:
private void OnBeforePrint(object sender, PrintEventArgs e)
{
object value = this.GetCurrentColumnValue("YourField");
if (value != null)
{
yourCell.Text = String.Format("{0:N2}", value.ToString()).Replace(".00", "");
}
}
Based on the feedback I've receieved here in the comments, it's not possible to perform the formatting I'd like to do with only providing a string format; I would need to insert some code either when I provide the data to the report (and then remove any and all formatting from the report) and perform all summing functions at the code level (to ensure that the sum values have the expected decimal places), or I would need to accept .00 at the end of, for example, some amount of yen (100 JPY would never be represented as 100.00 JPY, as an example).
This is a bit of an esoteric case, but it's good to know!

Sorting Date&Time string

I have these below strings to sort (String Format: 121030-1833 --> YYDDMM-HHMM)
String Example:
121030-1833
120823-2034
120807-2014
120627-2316
120525-1136
111226-1844
I want to sort them from latest to old format.
Which sort method will be the best to use here?
Updated problem statement
dictionary[String,string] "dictLocation" values with me, Want to sort the Dictionary according to its key (Key-YYMMDD-HHMM, latest to oldest)
{[110901-1226, sandyslocation.110901-1226]}
{[120823-2034, andyslocatio.120823-2034]}
{[110915-1720, mylocation.110915-1720]}
{[121030-1833, mylocation.121030-1833]}
I am trying this var latestToOldest = dictLocation.OrderBy(key => key.Key)
It not giving me proper result, Is there anything i am missing ?
As it happens, just sorting them in a descending way will work:
var latestToOldest = original.OrderByDescending(x => x);
That's assuming you want to assume all values are within the same century. (If you can possibly change the format, I'd suggest using a 4-digit year for clarity.)
However, I would recommend parsing the values into DateTime values as early as possible. Whenever you can, keep your data in its most "natural" form. Fundamentally these are dates and times, not strings - so convert them into that format early, and keep them in that format as long as you possibly can.
var sortedDateStrings = dateStrings.Sort().Reverse();
// or
var sortedDateStrings = dateStrings.OrderByDescending(x => x);

Format.exception C#/Asp.Net/SQL

I am getting the error "System.FormatException : input string was not correct".
TextBox2.Text = objnm.rupees(Convert.ToInt64(Convert.ToDecimal(txtWOrds.Text.Trim())));
First, you don't need to convert it to decimal (Convert.ToDecimal) and then to Int64 (Convert.ToIn64).
Second, if txtWOrds.Text is not a number or is empty, than you will get this exception. Make sure that it is a number.
Third, if your value is a number, than your problem likes somewhere in objnm.rupees()
You should check the input in case its empty, like string.IsNullOrEmpty(txtWOrds.Text) then proceed with the parsing of the contents of the textbox.
Also you should be using TryParse which evaluates if the text can be parsed and if true you can use the value of the out parameter of this method.
In your case it could fail if the TextBox is empty.
Also if its anything related to money/currency not sure if you need the conversion to Long (seems like a mismatch there, please clarify. If you want a specific set of decimal points then it would be better to use decimal.Round )
Decimal value = default(decimal);
bool isValid = decimal.TryParse(txtWOrds.Text.Trim(), out value);
if (isValid)
{
//your code using output 'value'
}
Remove Convert.Int64 and just use Convert.ToDecimal (ideally you should use decimal.TryParse). Also, ensure that the input textbox contains the correct type (a decimal)

How to get cell value with applied formatting (formatted cell value) with OpenXML SDK

I've been googling and searching on the site for the answer, but I couldn't find a solution - everywhere people mostly discuss how to add new number format to the document and apply it.
What I need is to get the cell value as a string with applied formatting - i.e. same string as would be displayed by Excel.
I already figured that there's no easy way or built-in function which would return the readymade formatted value for a cell.
So it seems to me that to get the value I need to do two things:
1. Get the format string.
2. Format the cell value using this string.
But I have problems with both steps.
One can easily get CellFormat instance which would contain NumberFormatId:
CellFormat cellFormat = (CellFormat) document.WorkbookPart.WorkbookStylesPart.Stylesheet.CellFormats.ElementAt(cell.StyleIndex);
But how to get the format string with this NumberFormatId, if the id corresponds to one of standard predefined formats? (i.e. is below 160) They are not in the spreadsheet document and I can't believe that they should be hardcoded in the application.
Also, once the format string is somehow obtained, how to apply it to the cell value? So far I understand, the code should check the type of the cell value and if is Number - convert it to string using the format string.
I found this page which mentions using Microsoft.Office.Excel.Interop, but I would prefer to stay with OpenXML SDK only.
Overall, I'm very surprised that it's so difficult to find a definitive answer to this question on the Web as I thought that this would be something which many developers need in their daily work.
Men, this is a hard one... I will be adding here things that i found that could be worth..
First is to get the numbering format of the cell (once you have the CellFormat:
string format = excel.WorkbookPart.WorkbookStylesPart.Stylesheet.NumberingFormats.Elements<NumberingFormat>()
.Where(i => i.NumberFormatId.ToString() == cellFormat.NumberFormatId.ToString())
.First().FormatCode;
For more information about this you can go to: NumberingFormats
Im trying to find out how to apply this format to the cell.CellValue property... I think thats the way you have to go!
Ok, reading the ClosedXml code (its open source), seems to be easy to get the format.
Simply convert the value text to its type (int, double, etc) and call the ToString method passing the format. I was trying do that with the String.Format and didnt work. Ive tested the ToString and it works, but something still missing.
I recommend to you to look at this class and get the code from the method GetFormattedString() as #El G tell in his comment.
Bassicaly you will have to add something like this:
double d = double.Parse(cell.CellValue.InnerText);
string val = d.ToString(format);
Hope it helps you...
If you want to take cell value with applied formatting, same as displayed in Excel, use .Text property of Cell object. Like this:
String formattedValue = cell.Text

How to format a number as percentage without the percentage sign?

How do I in .NET format a number as percentage without showing the percentage sign?
If I have the number 0.13 and use the format string {0:P0} the output is 13 %.
However I would like to get 13 instead, without having to multiply the number by 100 and using the format string {0:N0}.
(Background: In ASP.NET I have a GridView with a BoundField where I would like to display a number as percentage but without the percentage sign (%). How do I do that?)
Thanks for the answers. At the time of editing 4 out of 6 suggest what I would like to avoid, as explained above. I was looking for a way to use a format string only, and avoid multiplying by 100 and using {0:N0}, but the answers indicate that's impossible...
Solved by using the accepted solution by Richard:
public class MyCulture : CultureInfo
{
public MyCulture()
: base(Thread.CurrentThread.CurrentCulture.Name)
{
this.NumberFormat.PercentSymbol = "";
}
}
Thread.CurrentThread.CurrentCulture = new MyCulture();
Define a custom culture with its own NumberFormatInfo which returns String.Empty for its PercentSymbol property.
Then use that custom culture for impacted pages (or for the whole application). This could be done by cloning from the default so other regional settings are preserved.
Why don't you just multiply the number by 100 and use your "{0:N0}" format string? That seems to me to be the easiest solution.
Unless you can come up with a viable reason why that's out of the question, that's my advice. It's not rocket science :-)
but multiplying by 100 is exactly what you want!
protected void myGrdiView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
myObjectType ot = (myObjectType)e.Row.DataItem;
ot.myNumber = ot.myNumber * 100; // multiply by 100
}
}
and in the HTML
<asp:BoundField DataType="myNumber" HeaderText="%" StringFormat="{0:N0}" />
The MSDN* has this under "Custom Numeric Format Strings":
The presence of a '%' character in a
format string causes a number to be
multiplied by 100 before it is
formatted. The appropriate symbol is
inserted in the number itself at the
location where the '%' appears in the
format string. The percent character
used is dependent on the current
NumberFormatInfo class.
But the example shows that it also outputs the % sign - not what you want, but perhaps settable to nothing via the NumberFormatInfo class?
However, I agree with Pax and can't see why do don't go with the * 100 and {0:N0}
**Accessing from within Visual Studio so no link*
How about this...
String.Format("{0:P0}",0.13).Replace("%","")
EDIT: This should work across cultures:
var percentSymbol = CultureInfo.CurrentCulture.NumberFormat.PercentSymbol;
String.Format("{0:P0}",0.13).Replace(percentSymbol,"")
There is also this solution which may be more elegant but slightly more code.
How about a trim?
double d = .102;
string percent = d.ToString("P0").Trim(' ', '%');
A points to consider first, a percentage displayed without a % is a number so lets ignore the percentage aspect. You want to know how to display a number that's 1 or less as 100 or less. I appreciate that it's bound so you can't modify it at display time so why not modify it at query time, i.e. SELECT (value*100) AS Percentage, ...?
You could also try something like
string newString = "0.13".Replace("0.", string.Empty) + "%";
Here is an example using NumberFormatInfo as #Richard suggested:
string.Format(new NumberFormatInfo { PercentSymbol = string.Empty }, "{0:0%}", 0.123); // => 12
Here is another shorter and cleaner way to do it.
$"{rate * 100:F2}"

Categories

Resources