I'm new to the C#/MVC world. I spend a lot of time today figuring out how to display a DateTimeOffset object in the format i want. Finally got it working this way.
Html.TextBoxFor(model => model.DeliveryDate,"{0:MM/dd/yyyy}",
new { htmlAttributes = new { #class = "datepicker" } })
But I still don't understand the importance of '0' in the format string. the page breaks if i replace the 0 with any other number or totally remove it. Can someone help me understand this?
From String.Format Method
The {0} in the format string is a format item. 0 is the index of the object whose string value will be inserted at that position. (Indexes start at 0.) If the object to be inserted is not a string, its ToString method is called to convert it to one before inserting it in the result string.
That's a format string with parameters (like used in e.g. Console.WriteLine, or string.Format). The {0} would be the placeholder for the first argument, and {0:mm/dd/yyyy} is simply a format string to convert the first argument to a string.
When you use the string.Format you can pass the space for arguments like {0}, {1}, etc which is the indexes you pass as arguments for the method. It is the same for asp.net razor helpers.
You also can provide the format after the index separating by :, for sample: {0:0.00} as format for a number with 2 decimals places or {1:dd/MM/yyyy} for dates etc.
String Interpolation
There is a new way to implement it using the String Interpolation. Basically, you can concat the values on your string without generating new strings. For sample:
var i = 18;
var s = $"You are {age} years old.";
Since you start the string with $, you can pass arguments between { and }. You also can use the same formats to format your data as you use on string.Format. For sample:
var today = $"Today is {DateTime.Now:D}";
var date = DateTime.Now.Add(1);
var tommorrow = $"Tommorrow is {date:dd/MM/yyyy}";
See the documentation for String.Format():
https://msdn.microsoft.com/en-us/library/system.string.format.aspx
In a nutshell, when the model is rendered to HTML text, the DeliveryDate object value will be passed to String.Format(), where {0} indicates the index of the first value in an array of values being passed to Format(). So {0:MM/dd/yyyy} just means to format the first value in the array using date components. Basically, it will do something like this internally:
String s = SomeValueArray[0].ToString("MM/dd/yyyy");
0 is a placeholder for your argument / property (in this case) DeliveryDate.. Similar to String.Format examples... so when your View is rendered.. the 0 will be replaced with whatever value that DeliveryDate is holding in the format MM/dd/yyyy
Related
I have as input the string format CST-000000 and an integer with value 1
Upon using
string result = string.Format("CST-000000", 1);
the expected result should be CST-000001 instead of CST-000000
How could i create this string format dynamically?
For example
- CST-000 should produce CST-001
- HELLO000 should produce HELLO001
- CUSTOMER0000 should produce CUSTOMER0001
Assuming that:
You receive your format string from somewhere and you can't control what it looks like
Your format string ends with 1 or more zeros
If the format string is e.g. CST-00000 and your value is 123, you want the result to be CST-00123
You can do something like this:
Inspect your format string, and separate out the stuff at the beginning from the zeros at the end. It's easy to do this with Regex, e.g.:
string format = "CST-000000";
// "Zero or more of anything, followed by one or more zeros at the end of the string"
var match = Regex.Match(format, "(.*?)(0+)$");
if (!match.Success)
{
throw new ArgumentException("Format must end with one or more zeros");
}
string prefix = match.Groups[1].Value; // E.g. CST-
string zeros = match.Groups[2].Value; // E.g. 000000
Once you have these, note the "Zero placeholder" in this list of custom numeric format strings -- you can write e.g. 123.ToString("0000") and the output will be 0123. This lets you finish off with:
int value = 123;
string result = prefix + value.ToString(zeros);
See it on dotnetfiddle
String.Format requires a placeholder {n} with a zero-based argument number. You can also add it a format {n:format}.
string result = String.Format("CST-{0:000000}", 1);
You can also use String interpolation
string result = $"CST-{1:000000}"
The difference is that instead of a placeholder you specify the value directly (or as an expression). Instead of the Custom numeric format string, you can also use the Standard numeric format string d6: $"CST-{1:d6}"
If you want to change the format template dynamically, String.Format will work better, as you can specify the format and the value as separate arguments.
(Example assumes an enum FormatKind and C# >= 8.0)
int value = 1;
string format = formatKind switch {
FormatKind.CstSmall => "CST-{0:d3}",
FormatKind.CstLarge => "CST-{0:d6}",
FormatKind.Hello => "HELLO{0:d3}",
FormatEnum.Customer => "CUSTOMER{0:d4}"
};
string result = String.Format(format, value);
Also note that the value to be formatted must be of a numeric type. Strings cannot be formatted.
See also: Composite formatting
It seems .toString("CST-000"), .toString("HELLO000") and so on, does the trick.
ToString and String.Format can do much more than use predefined formats.
For example :
string result = string.Format("CST-{0:000000}", 1);
string result = 1.ToString("CST-000000");
Should both do what you want.
(Of course you could replace "1" by any variable, even a decimal one).
Background: We have a system that receives data from another backend system. We handle the displaying of that data, and we have our own XML templates to control how certain things are displayed (i.e. we have our own column templates to dictate what the column headers are, etc.) One thing we would like to support is the ability to provide a mask for these column templates that would apply to the values coming from the backend. Below is a scenario that I'm having trouble with.
Problem: I can't seem to get a simple string format working. I'd like to format a STRING value of four digits (i.e. "1444") in a time format (i.e. "14:44"). I've tried:
String.Format("{0:00:00}", "1444")
Note the importance of the input being a STRING. If I supply an int value, the format will work. The reason I cannot use this is because all the data we receive from the backend is in string format, and we'd like for this to be generic (so casting isn't really an option).
By generic, I mean I'd like to specify a mask in our own XML templates, something like:
<MyColumnTemplate Id="MyColumn" Mask="00:00" />
and to use that mask in a string format call for string values? If the mask fails, we could just simply return the original value (as the String.Format() method already does by default).
Edit: To help clarify, here is a simplified version of what I'd like to be able to do in code:
string inputValue = "1444";
string maskValueFromXml = "00:00";
string mask = "{0:" + maskValueFromXml + "}";
string myDesiredEndResult = String.Format(mask, inputValue);
The thing is you are working string to string,since you ask for time and phone number they are all numbers then try this trick(if we can call it that :)):
string result = string.Format("{0:00:00}", int.Parse("1444"));
For phone number:
string result = string.Format("{0:000-000-0000}", int.Parse("1234560789"));
You can even place your desired masks in a dictionary for example and do this:
Dictionary<string, string> masks = new Dictionary<string, string>();
masks.Add("Phone", "{0:000-000-0000}");
masks.Add("Time", "{0:00:00}");
string test = "1234560789";
string result = string.Format(masks["Phone"], int.Parse(test));
Try with DateTime.TryParseExact, e.g:
DateTime dateEntered;
string input = "1444";
if (DateTime.TryParseExact(input, "HH:mm", System.Globalization.CultureInfo.CurrentCulture, System.Globalization.DateTimeStyles.None, out dateEntered))
{
MessageBox.Show(dateEntered.ToString());
}
else
{
MessageBox.Show("You need to enter valid 24hr time");
}
After that, you can use string.Format, predefined formats on MSDN.
In C#.Net, here's a simple example of how to format numbers into strings using custom format strings:
(example taken from: http://www.csharp-examples.net/string-format-int/)
String.Format("{0:+### ### ### ###}", 447900123456); // "+447 900 123 456"
String.Format("{0:##-####-####}", 8958712551); // "89-5871-2551"
Is there a way to convert this formatted string back into a long/integer ? Is there someway to do this :
long PhoneNumber = Int32.Parse("89-5871-2551", "{0:##-####-####}");
I saw that DateTime has a method ParseExact which can do this work well. But I did not see any such thing for int/long/decimal/double.
You can regex out all of the non numeric numbers, and what you're left with is a string of numbers that you can parse.
var myPhoneNumber = "89-5871-2551";
var strippedPhoneNumber = Regex.Replace(myPhoneNumber, #"[^\d]", "");
int intRepresentation;
if (Int32.TryParse(strippedPhoneNumber, out intRepresentation))
{
// It was assigned, intRepresentation = 8958712551
// now you can use intRepresentation.
} else {
// It was not assigned, intRepresentation is still null.
}
Well, you can always do
long PhoneNumber = Int32.Parse("89-5871-2551".
Replace(new char[]{'-','+',whatever..}).Trim());
By the way, considering that you're parsing a string received from some IO, I would suggest to use more secure (in terms of conversion) Int32.TryParse method.
The way like you described doesn't actually exist.
Just Regex out all of the non-numeric characters, then parse that string.
I am getting the following values from database:
99, 12, 12.2222, 54.98, 56, 17.556
Now I want to show that values like below:
99%, 12%, 12.22% , 54.98% , 56%, 17.55%
Please give me any suggestion to acchive this.
Its very easy in C#:
[EDIT]
var val = 99.569;
string result = string.Format("{0:0.##}%", val);
You can take a look for Format method of string class:
http://msdn.microsoft.com/en-us/library/fht0f5be.aspx
and I recomend you to take a look on custom format strings:
http://msdn.microsoft.com/en-us/library/0c899ak8.aspx
Use the ToString method that takes a string format - the format you want is "P2" or the custom format #0.##%. Both of these formatting options multiply by 100, expecting your data to be in standard percent format so you will need to divide to accomadate and use it.
To use ToString without the divide you can use "#0.##\%" which will format the numeric part and include the percent sign as a literl, this is the equivilent for ToString as the format from Anton Semenov's answer using the string.Format function on this thread.
Msdn article - Standard Formats
Msdn article - Custom Formats
to formart 12.2222 use f
string.Format("{0:f}%", 12.2222); //output 12,22%
Try this Out
List<double> myList = new List<double>();
myList.Add(0.1234);
myList.Add(99);
myList.Add(12.1234);
myList.Add(54.98);
foreach (double d in myList)
{
string First = string.Format("{0:0.00%}", d); //Multiply value by 100
Console.WriteLine(First);
string Second = string.Format("{0:P}", d);//Multiply value by 100
Console.WriteLine(Second);
string Third = string.Format("{0:P}%", d.ToString());//Use this One
Console.WriteLine(Third);
string Four = d.ToString() + "%"; //Not a good idea but works
Console.WriteLine(Four);
Console.WriteLine("=====================");
}
Console.ReadLine();
I have made a little trick here {0:P} will multiply your given value by 100 and then show it but you just want to place a % sign after value so first convert the given value to TOString than apply {0:p}
If you want to specify the number of decimal places to 2 (ie. not 12.2222%, but 12.22%), then use:
val.ToString("0.00") + "%"
Note that this will round the number off, so 12.226 would be shown as 12.23%, etc.
Before using String.Format to format a string in C#, I would like to know how many parameters does that string accept?
For eg. if the string was "{0} is not the same as {1}", I would like to know that this string accepts two parameters
For eg. if the string was "{0} is not the same as {1} and {2}", the string accepts 3 parameters
How can I find this efficiently?
String.Format receives a string argument with format value, and an params object[] array, which can deal with an arbitrary large value items.
For every object value, it's .ToString() method will be called to resolve that format pattern
EDIT: Seems I misread your question. If you want to know how many arguments are required to your format, you can discover that by using a regular expression:
string pattern = "{0} {1:00} {{2}}, Failure: {0}{{{1}}}, Failure: {0} ({0})";
int count = Regex.Matches(Regex.Replace(pattern,
#"(\{{2}|\}{2})", ""), // removes escaped curly brackets
#"\{\d+(?:\:?[^}]*)\}").Count; // returns 6
As Benjamin noted in comments, maybe you do need to know number of different references. If you don't using Linq, here you go:
int count = Regex.Matches(Regex.Replace(pattern,
#"(\{{2}|\}{2})", ""), // removes escaped curly brackets
#"\{(\d+)(?:\:?[^}]*)\}").OfType<Match>()
.SelectMany(match => match.Groups.OfType<Group>().Skip(1))
.Select(index => Int32.Parse(index.Value))
.Max() + 1; // returns 2
This also address #280Z28 last problem spotted.
Edit by 280Z28: This will not validate the input, but for any valid input will give the correct answer:
int count2 =
Regex.Matches(
pattern.Replace("{{", string.Empty),
#"\{(\d+)")
.OfType<Match>()
.Select(match => int.Parse(match.Groups[1].Value))
.Union(Enumerable.Repeat(-1, 1))
.Max() + 1;
You'll have to parse through the string and find the highest integer value between the {}'s...then add one.
...or count the number of sets of {}'s.
Either way, it's ugly. I'd be interested to know why you need to be able to figure out this number programatically.
EDIT
As 280Z28 mentioned, you'll have to account for the various idiosyncrasies of what can be included between the {}'s (multiple {}'s, formatting strings, etc.).
I rely on ReSharper to analyze that for me, and it is a pity that Visual Studio does not ship with such a neat feature.