Is it true that String.Format works 2 ways:
if we use built-in format such as C, N, P.... it will take locale settings into account?
if we use custom format code such as #,##0.000 it will NOT take locale settings into account?
In my code, I use method like this
String.Format("{0:#.##0,000}", value);
because my country use comma as decimal separator
but the result still is: 1,234.500 as if it consider dot as decimal separator.
Please help!
You want to use CultureInfo:
value.ToString("N", new CultureInfo("vn-VN"));
Using String.Format:
String.Format(new CultureInfo("vi-VN"), "N", value);
Since you're in Hanoi (from profile), I used Vietnam's code, which is vn-VN.
This works. The formatted value is 123.456,789 which is correct per es-ES
IFormatProvider iFormatProvider = new System.Globalization.CultureInfo("es-ES");
var value = 123456.789001m;
string s = value.ToString("#,##0.000", iFormatProvider);
string s2 = string.Format(iFormatProvider, "{0:#,##0.000}", value);
FormattableString fs = $"{value:#,##0.000}";
string s3 = fs.ToString(iFormatProvider);
Note that the , and . are using a 'standard' en-US style, but .ToString() and string.Format() with a format provider does the right thing.
You should make sure your thread uses the correct culture:
Thread.CurrentThread.CurrentCulture = CultureInfo.CurrentCulture
Thread.CurrentThread.CurrentUICulture = CultureInfo.CurrentCulture
FrameworkElement.LanguageProperty.OverrideMetadata(GetType(FrameworkElement), New FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)))
Related
if (!IsPostBack && !Page.IsCallback)
{
double OffsetHrs = GetTimeZoneOffsetFromCookie();
string dateFormat = ServiceManager.LocalizationService.GetString("AppHeaderTop", "DateFormat", "g");
CultureSelected CultureSelected = GetCultureSelected();
ASPxLabelCurrentTime.Text = DateTime.Now.ToUniversalTime().AddHours(-OffsetHrs).ToString(dateFormat);
if (CultureSelected.CultureCode != "en-US")
{
DateTimeFormatInfo usDtfi = new CultureInfo("en-US", false).DateTimeFormat;
DateTimeFormatInfo currentDtfi = new CultureInfo(CultureSelected.CultureCode, false).DateTimeFormat;
ASPxLabelCurrentTime.Text = Convert.ToDateTime(ASPxLabelCurrentTime.Text, usDtfi).ToString(currentDtfi.ShortDatePattern); //what can i Use here ?
}
Let say Output of ASPxLabelCurrentTime.Text
for en-US culture is 11/2/2015 4:14 PM (70)
If I select specific culture I want this datetime 11/2/2015 4:14 PM (70) to appear in that specific culture format.
Your question seems unclear but I try to give a shot.
First of all, what is this (70) exactly? Where is this came from? en-US culture can't parse this string without using it in a string literal delimiter with ParseExact or TryParseExact methods. On the other hand, since you assing ASPxLabelCurrentTime.Text the result of the DateTime.Now.ToUniversalTime().AddHours(-OffsetHrs).ToString(dateFormat) code, I don't believe this (70) part is really an issue on this question.
Second, If I understand clearly, the problem seems the usage of DateTime.ToString(string) method.
ASPxLabelCurrentTime.Text = Convert.ToDateTime(ASPxLabelCurrentTime.Text, usDtfi)
.ToString(currentDtfi.ShortDatePattern);
// ^^^ Problem seems here
Okey let's say you successfully parse this ASPxLabelCurrentTime.Text with usDtfi culture (which is en-US), but with this .ToString(string) method, you are not using currentDtfi settings actually, you are using CurrentCulture settings when you generate formatted string representation of your DateTime.
From DateTime.ToString(String) doc;
Converts the value of the current DateTime object to its equivalent
string representation using the specified format and the formatting
conventions of the current culture.
Since we don't know what GetCultureSelected method returns exactly, it may or may not be the same culture with currentDtfi.
I strongly suspect, you can solve this problem to using that culture as a second parameter in ToString method as;
ASPxLabelCurrentTime.Text = Convert.ToDateTime(ASPxLabelCurrentTime.Text, usDtfi)
.ToString(currentDtfi.ShortDatePattern, currentDtfi);
IF this (70) is really part of on your string, you need to ParseExact or TryParseExact methods to supply exact format of it.
string s = "11/2/2015 4:14 PM (70)";
DateTime dt;
if(DateTime.TryParseExact(s, "MM/d/yyyy h:mm tt '(70)'", CultureInfo.GetCultureInfo("en-US"),
DateTimeStyles.None, out dt))
{
ASPxLabelCurrentTime.Text = dt.ToString(currentDtfi.ShortDatePattern, currentDtfi);
}
When I tried to convert something like 0.1 (from user in textbox), My value b is always false.
bool b = Decimal.TryParse("0.1", out value);
How can it be here to work?
Specify the culture for the parsing. Your current culture uses some different number format, probably 0,1.
This will successfully parse the string:
bool b = Decimal.TryParse("0.1", NumberStyles.Any, CultureInfo.InvariantCulture, out value);
Too late to the party, but I was going to suggest forcing the culuture to en-US but Invariant is a better sln
decimal value;
bool b = Decimal.TryParse("0.1", NumberStyles.Any, new CultureInfo("en-US"), out value);
Use Culture in overload method
I want to convert "372551.40" to decimal. But I need to see it after converting this format 372.551,40.
To convert it to decimal, you can use:
decimal decimalValue = 0.0;
decimalValue = decimal.Parse("372551.40");
or
decimal.TryParse("372551.40", out decimalValue);
To display it in a specific format you can do:
CultureInfo tr = new CultureInfo("tr-TR");
string formattedValue = decimalValue.ToString("c", tr);
//result will be 372.551,40 YTL
formattedValue = decimalValue.ToString("0,0.00", tr);
//result will be 372.551,40
string value;
Decimal number;
value = "16,523,421";
if (!Decimal.TryParse(value,out number))
{
// set it to something if the "Value" is not a number
number = -1;
}
Do the following:
string s = "372551.40";
CultureInfo cultureInfo = CultureInfo.InvariantCulure; //Use relevant culture in which your number is formatted. In this case InvariantCulture would do.
decimal d;
bool succesful = Decimal.TryParse(s, NumberStyles.Number, cultureInfo, out d); //it will try to parse the string according to the specified culture.;
If you have a succesful parse, then d will store the numeric value represented by s as a decimal value which you can output into any formatted string and culture the ToString() or Format.String().
Note that if the culture in which the number represented by s is the current system culture, then you can use the TryParse(string s, out decimal d) overload where it is not necessary to specify NumberStyles and IFormatProvider.
Something like this?
string s = "372551.40";
decimal d;
if (decimal.TryParse(s, out d))
{
var culture = new CultureInfo("de-DE");
var result = d.ToString("0,0.00", culture);
// result is "372.551,40"
}
You can also use the current culture instead of hard-coding one like I did.
Hope this helps,
John
Use decimal.Parse() to make it a decimal. Then you have many formatting options.
The display as you mentioned is dependent on the culture setting.
Make your new CultureInfo and in the NumberFormat, you will have to modify some settings like Decimal Separator as , and Thousands Separator as . and provide this to the ToString method of the variable holding the decimal value.
This should display the value as 372.551,40
You can use .Replace
string string 1 = "372,551.40";
string1.Replace(",","");
decimalVal = System.Convert.ToDecimal(StringVal);
//shows 372551.40
You can always throw that into a for loop if you are playign with a ton of numbers.
You can find more in depth info and some examples on MSDN
The overload of decimal.Parse that takes an IFormatProvider will allow you to parse strings containing numbers with periods as decimal point symbols (in case the standard is a comma in your culture).
You can use ToString on the resulting decimal to format it with a comma by passing in an appropriate IFormatProvider. Both CulturInfo and NumberFormatInfo implement IFormatProvider.
You can get an instance of CultureInfo with the following code (this one is for English in Australia).
new CultureInfo("en-AU")
Also note that decimal.TryParse is a good alternative to the decimal.Parse method if you expect incorrectly formatted strings as it will allow you to handle them without an exception being raised.
The following code should give you the desired result (you wrote in one of the comments that the target system is SAP and that the culture is probably German (de-DE)).
var yourString = "372551.40";
var yourDecimal = decimal.Parse(yourString, CultureInfo.InvariantCulture);
var yourFormattedDecimal = yourDecimal.ToString(new CultureInfo("de-DE"));
From MSDN:
string value;
decimal number;
// Parse an integer with thousands separators.
value = "16,523,421";
number = Decimal.Parse(value);
Console.WriteLine("'{0}' converted to {1}.", value, number);
// Displays:
// 16,523,421' converted to 16523421.
Cheers
You can create custom NumberFormatInfo:
string s = "372551.40";
var dec = decimal.Parse(s, CultureInfo.InvariantCulture);
var nfi = new CultureInfo("en-US", false).NumberFormat;
nfi.NumberGroupSeparator = ".";
nfi.NumberDecimalSeparator = ",";
var res = dec.ToString("n", nfi);
var resDecimal = decimal.Parse(res, nfi);
Output is exactly what you need: 372.551,40
Thanks for taking the time to assist me with my problem.
In the code I'm writing, I'm iterating through a table, I get the appropriate values (confirmed it using the debugger) and I'm parsing them to the appropriate types before and finally I add them to an Object to be serialized into XML.
However, I bumped into a problem and that is I can't seem to find a way to parse the string into a decimal value. Take a look:
if (DateTime.TryParse(dateString, culture, styles, out date))
{
decimal LastValue;
string vrednost = String.Format("{0:0,0.0}",
row.SelectSingleNode("td[2]").InnerText);
if (Decimal.TryParse(vrednost, out LastValue))
list.Add(new StockEntry
{
Date = date,
PoslednaCena = LastValue
...
}
Note that the value of vrednost is 4.451,00 and I suspect that if I convert it to 4,451.00 it will get parsed.
I've succeeded in parsing date into the appropriate datetime value. However, the value of LastValue is always 0. I've exhausted all the resources that I know of. Do you have any idea how to solve my problem?
Thank you in advance!
This formatting will do nothing because you can't format strings like this. You have to use parse method with additional parameters and specify your own format
string s2 = "4.451,00";
NumberFormatInfo numberFormatInfo = new NumberFormatInfo();
numberFormatInfo.NumberDecimalSeparator = ",";
numberFormatInfo.NumberGroupSeparator = ".";
var d = decimal.Parse(s2, numberFormatInfo);
I think that your problem might be due to the culture used for the parsing. Try using CultureInfo.InvariantCulture for your parsing. It should work with "," as thousands separator and "." as decimal separator.
Decimal.TryParse(vrednost, NumberStyles.Number, CultureInfo.InvariantCulture, out LastValue);
If you want to swap them you could use another culture. Italian, for instance, works with your format (not sure about the others), so your code for "4.451,00" would look like:
Decimal.TryParse(vrednost, NumberStyles.Number, CultureInfo.GetCultureInfo("it"), out LastValue);
If you want to use a custom culture instead of forcing some culture which does what you want you can simply create your NumberFormatInfo class and pass it to the parse method.
NumberFormatInfo decimalNumber = new NumberFormatInfo();
decimalNumber.NumberDecimalSeparator = ",";
decimalNumber.NumberGroupSeparator = ".";
Decimal.TryParse(vrednost, NumberStyles.Number, decimalNumber, out LastValue);
Your row.SelectSingleNode("td[2]").InnerText is a string and you are trying to format it like a decimal.
Try parsing it directly:
decimal LastValue;
string vrednost = row.SelectSingleNode("td[2]").InnerText;
if (Decimal.TryParse(vrednost, out LastValue))
Check your cultureinfo at first and set it appropriately.
CultureInfo MyUsersCulture = Thread.CurrentThread.CurrentCulture;
Console.WriteLine("The culture: "+ MyUsersCulture.Name);
Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");
ConsoleWriteLine("The culture: " + Thread.CurrentThread.CurrentCulture);
Is there a way of setting or overriding the default DateTime format for an entire application. I am writing an app in C# .Net MVC 1.0 and use alot of generics and reflection. Would be much simpler if I could override the default DateTime.ToString() format to be "dd-MMM-yyyy". I do not want this format to change when the site is run on a different machine.
Edit -
Just to clarify I mean specifically calling the ToString, not some other extension function, this is because of the reflection / generated code. Would be easier to just change the ToString output.
The "default format" of a datetime is:
ShortDatePattern + ' ' + LongTimePattern
at least in the current mono implementation.
This is particularly painful in case you want to display something like 2001-02-03T04:05:06Z i.e. the date and time combined as specified in ISO 8606, but not a big problem in your case:
using System;
using System.Globalization;
using System.Threading;
namespace test {
public static class Program {
public static void Main() {
CultureInfo culture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
culture.DateTimeFormat.ShortDatePattern = "dd-MMM-yyyy";
culture.DateTimeFormat.LongTimePattern = "";
Thread.CurrentThread.CurrentCulture = culture;
Console.WriteLine(DateTime.Now);
}
}
}
This will set the default behavior of ToString on datetimes to return the format you expect.
It is dependent on your application's localization-settings. Change that accordingly to get correct format.
Otherwise have a helper-class or an extension-method which always handles your DateTime.
public static string ToMyDateTime(this DateTime dateTime) {
return dateTime.ToString("dd-MMMM-yy");
}
DateTime.ToString() combines the custom format strings returned by the ShortDatePattern and LongTimePattern properties of the DateTimeFormatInfo. You can specify these patterns in DateTimeFormatInfo.CurrentInfo.
I've never tried this my self.
If you want to be sure that your culture stays the same, just set it yourself to avoid troubles.
System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("nl-BE");
System.Threading.Thread.CurrentThread.CurrentCulture = ci;
System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
The above example sets the culture of the thread to Belgian-Dutch.
CurrentCulture does all the date and time handling and CurrentUICulture handles UI localization like resources.
I'm not sure if this would work for a web app, but you could try to set the DateTimeFormat property for the current culture.
Check this and specially this.
Using .Net 6 put something like this in your program.cs after app.UseAuthentication()/app.UseAuthorization() and before app.MapControllerRoute(...):
var ci = new CultureInfo("en-US");
ci.DateTimeFormat.ShortDatePattern = "MM/dd/yyyy";
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new Microsoft.AspNetCore.Localization.RequestCulture(ci),
SupportedCultures = new List<CultureInfo> { ci },
SupportedUICultures = new List<CultureInfo> { ci }
});
Here I'm changing the short date format, but you can also change currency symbol, decimal separator, etc.
You can write an ExtensionMethod like this:
public static string ToMyString(this DateTime dateTime)
{
return dateTime.ToString("needed format");
}