ToLongDateString() not working - c#

string[] splitDate = DateOfBirth.ToLongDateString().Split(new char[] { ',', ' ' });
foreach (string s in splitDate)
{
Console.Write(s);
}
For input like "15/08/1991", it gives the output "Thursday August 15 1991" on my machine but gives output "August 15 1991" on another machine.
The code works fine on my system but fails on another system due to above reason. Any help is appreciated.

This happens, because:
The string returned by the ToLongDateString method is culture-sensitive
as it is stated here.
In order you fix it you have to specify the CurrentCulture property of the CurrentTread.
Thread.CurrentThread.CurrentCulture = new CultureInfo("...");
However, that will affect everything that relies on the culture in your code.
Here is a list of predefined cultures, that you could use.

Soner's comment is correct. Check out the documentation on how to set the culture using CurrentCulture. However, from your code it seems that you just need a string that contains a date and you can do that easily with DateOfBirth.Day, DateOfBirth.Month, DateOfBirth.DayOfWeek etc.

that is because of the culture and region settings of windows.
if u want to do it you can specify the culture you want to use as parameter.
DateTime.Now.ToString(new CultureInfo("en-GB"));
you can specify your date format as a second parameter as well :)

This is an old thread but this will be helpful for someone stil searching:
var CurrentCulture = Thread.CurrentThread.CurrentCulture; //Store the current culture
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("el-GR"); //Set a new culture
String FullString = MyDate.ToLongDateString(); //Get your string
Thread.CurrentThread.CurrentCulture = CurrentCulture; //Restore the environment.
Hope this helps.

Related

String Formatting to Currency C#

I am new to building web applications in ASP.NET and am trying to display a currency in Kenya Shillings. The symbol for the shilling is KES.
I have this:
<span>
<b>Price: </b><%#:String.Format(new System.Globalization.CultureInfo("sw-KE"), "{0:c}", Item.BeatPrice)%>
</span>
Culture name sourced from http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo%28v=vs.80%29.aspx.
However, the price shows as S3,000 instead of KES 3,000.
What do I need to do to format the price correctly?
If the format is not as you expect you can add custom string formatting:
String.Format("KES {0:N3}", Item.BeatPrice)
Hope this works.
It's better not to hardcode the CurrencySymbol, so you should use
var regionInfo = new RegionInfo("sw-KE");
var currencySymbol = regionInfo.ISOCurrencySymbol;
to get the correct CurrencySymbol for your culture.
//edit:
Or you can try this function:
public static string FormatCurrency(decimal value)
{
CultureInfo cultureInfo = Thread.CurrentThread.CurrentUICulture;
RegionInfo regionInfo = new RegionInfo(cultureInfo.LCID);
string formattedCurrency = String.Format("{0} {1:C}", regionInfo.ISOCurrencySymbol, value);
return formattedCurrency.Replace(cultureInfo.NumberFormat.CurrencySymbol, String.Empty).Trim();
}
Which gives you a formatted currency string based on the current UICulture.
If your machine's regional settings are properly set then you can use:
Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:c}", Item.BeatPrice));
It will automatically take culture based on your machine's regional settings.
Like Ondrej Svejdar said, there are two symbols, as in $ vs. USD:
var region = new System.Globalization.RegionInfo("sw-KE");
Console.WriteLine(region.CurrencySymbol); // "S"
Console.WriteLine(region.ISOCurrencySymbol); // "KES"
Note: When I ran this on IDEone (which compiles with Mono), the results were unexpected ("KES" and "Kenyan Shilling").
While using String.Format "c" or "C" gives you the currency symbol for specified culture. You are trying to show Currency ISO code for Kenya Shillings. Below code will display exactly what you wanted.
String.Format("{0} {1}", (new RegionInfo("sw-KE")).ISOCurrencySymbol, Item.BeatPrice)
If you don't change culture on your application easy way to do this.
String.Format("{0} {1}", "KES", Item.BeatPrice)
The best practice is to format the String to Currency format {0:C} and change the current thread UICulture or Culture to KES, and ASP.NET is smart enough to display the page accroding to your currunt culuture.
Note:
You can change culture by changing the culture of the browser (you can to do this for development purposes) but best practice change the culture programmatically, for example here I'm change the culture base on user Cookie and mu default culture is en-us like this.
protected override void InitializeCulture()
{
HttpCookie cultureCookie = Request.Cookies["culture"];
if (cultureCookie == null)
{
cultureCookie = new HttpCookie("culture", "en-US");
Response.Cookies.Add(cultureCookie);
}
Thread.CurrentThread.CurrentCulture = new CultureInfo(cultureCookie.Value);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(cultureCookie.Value);
base.InitializeCulture();
}

What's the use case for int32.Parse(String, IFormatProvider) over int32.Parse(String)?

When would it make sense to use int32.Parse(String, IFormatProvider)?
As far as I can tell, this and int32.Parse(String) uses NumberStyles.Integer anyway which only allows a plus, a minus, or digits, optionally surrounded by whitespace, so why does the locale format enter into the equation?
I know about thousand separators, but they don't matter because NumberStyles.Integer disallows them no matter your region.
Consider if you have culture where negative sign is M (minus). I am pretty sure it doesn't exist but just consider that you have something like that. Then you can do:
string str = "M123";
var culture = new CultureInfo("en-US");
culture.NumberFormat.NegativeSign = "M";
int number = Int32.Parse(str, culture);
This would result in -123 as value. This is where you can use int32.Parse(String, IFormatProvider) overload. If you don't specify the culture, then it would use the current culture and would fail for the value M123.
(Old Answer)
It is useful with string with thousand separator
Consider the following example,
string str = "1,234,567";
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");
int number = Int32.Parse(str, CultureInfo.CurrentCulture);
This would result in an exception since . is the thousand separator in German culture.
For
int number = Int32.Parse("1.234", NumberStyles.AllowThousands);
The above would parse successfully, since the German culture uses . as thousand separator.
But if you have current culture set as US then it would give an exception.
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
int number = Int32.Parse("1.234", NumberStyles.AllowThousands);
See: Int32.Parse Method (String, IFormatProvider)
The provider parameter is an IFormatProvider implementation, such as
a NumberFormatInfo or CultureInfo object. The provider parameter
supplies culture-specific information about the format of s. If
provider is null, the NumberFormatInfo object for the current culture
is used.
Well how about the thousand separators?
I think in USA they use ',' and in Greece they use '.'
USA: 1,000,000
Greece: 1.000.000
In case somebody else is also wondering about this 6 years later, there's still no point in using Int32.ToString(IFormatProvider?) or Int32.Parse(String, IFormatProvider?) since changing the culture makes no difference with the default format and NumberStyles.
You can run this simple test to verify:
using System;
using System.Globalization;
using System.Linq;
class IntToStringTest
{
static void Main()
{
var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
var input = -123456789;
var defaultOutput = input.ToString();
var outputCulturePairs = cultures.Select(c => (Output: input.ToString(c), Culture: c));
var parsedOutputs = outputCulturePairs.Select(p => Int32.Parse(p.Output, p.Culture));
Console.WriteLine(outputCulturePairs.All(p => p.Output == defaultOutput));
Console.WriteLine(parsedOutputs.All(o => o == input));
}
}
Edit 8/8/2020: This is only true for .NET Framework. On .NET Core some Arabic cultures use the minus sign AFTER the value.

How to format a string as Vietnamese currency?

If I set Format in [Region and Language] to US...
CultureInfo cul = CultureInfo.CurrentCulture;
string decimalSep = cul.NumberFormat.CurrencyDecimalSeparator;//decimalSep ='.'
string groupSep = cul.NumberFormat.CurrencyGroupSeparator;//groupSep=','
sFormat = string.Format("#{0}###", groupSep);
string a = double.Parse(12345).ToString(sFormat);
The result is: 12,345 (is correct)
But if I set the format in [Region and Language] to VietNam, then the result is: 12345
The result should be 12.345.
Can you help me? Thanks.
You are helping too much. The format specifier is culture insensitive, you always use a comma to indicate where the grouping character goes. Which is then substituted by the actual grouping character when the string is formatted.
This formats correctly:
CultureInfo cul = CultureInfo.GetCultureInfo("vi-VN"); // try with "en-US"
string a = double.Parse("12345").ToString("#,###", cul.NumberFormat);
You should actually use "#,#" to ensure it still works in cultures that have a uncommon grouping. It wasn't clear from the question whether that mattered or not so I punted for "#,###"
Try something like this:
var value = 8012.34m;
var info = System.Globalization.CultureInfo.GetCultureInfo("vi-VN");
Console.WriteLine(String.Format(info, "{0:c}", value));
The result is:
8.012,34 ₫
Oh, and with the value 12345 the result is 12.345,00 ₫.

Double.TryParse thousand separator returns unexpected result

I just ran into something very strange, and was just wondering if I was missing something.
I was trying to parse a string (with thousand separators) into a double, and found the below issue.
CultureInfo ci = CultureInfo.CurrentCulture; // en-ZA
string numberGroupSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator; //numberGroupSeparator = ,
string numberDecimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;//numberDecimalSeparator = .
string strValue = "242,445.24";
double try1;
double try2;
bool btry1 = Double.TryParse(strValue, out try1); //try1 = 242445.24 : btry1 = true
bool btry2 = Double.TryParse(strValue, NumberStyles.Any, null, out try2); //try2 = 0.0 : btry2 = false <- STRANGE
double try3 = Convert.ToDouble(strValue); //try3 = 242445.24
Now the reason why I didnt just want to use Convert.ToDouble is due to scientific notation which has given me some problems before.
Does anybody know why this might be?
EDIT:
I have update my current culture info.
Its working on my machine as expected, so I believe it has to do with the Current Culture. Try using CultureInfo.InvariantCulture instead of null in your TryParse
Double.TryParse(strValue, NumberStyles.Any,CultureInfo.InvariantCulture, out try2);
It is failing for your current specified culture en-ZA, I tried the following code and try2 is holding 0.0
Double.TryParse(strValue, NumberStyles.Any,new CultureInfo("en-ZA"), out try2);
Updated (correct) answer, after much digging
You say that your current culture is en-ZA, but checking
new System.Globalization.CultureInfo("en-ZA").NumberFormat.NumberGroupSeparator
we see that the value is the empty string and not "," as the question states. So if we set CultureInfo.CurrentCulture to new CultureInfo("en-ZA") then parsing fails even for try1.
After manually setting it to "," with
Thread.CurrentThread.CurrentCulture.NumberFormat.NumberGroupSeparator = ",";
it transpires that parsing into try1 is successful. Parsing into try2 still fails.
For the TryParse overload used in try2 the documentation is pretty clear that the current thread culture is used when the format provider is null, so something else must be going on...
After carefully comparing InvariantCulture.NumberFormat to that of the en-ZA culture, I noticed that the cultures also differ in their currency formats. Trying
Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencyGroupSeparator = ",";
Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencyDecimalSeparator = ".";
hit the jackpot: parsing succeeds! So what's really going on is that when using NumberStyles.All, the parse treats the number as currency.
The hypothesis can be verified if you try
double.TryParse(strValue,
NumberStyles.Any & ~NumberStyles.AllowCurrencySymbol, null, out try2);
which succeeds without needing to mess with the currency separators (of course the NumberGroupSeparator does have to be appropriate)!
The documentation says that 0.0 is returned, when the conversation fails.
Most likely TryParse returns false, and you should try calling Parse, to get an exception message that might tell you what is wrong.

String.Format Same Code Different View

I have a code like this;
GridView1.FooterRow.Cells[11].Text = String.Format("{0:c}", sumKV)
In my computer this code gives a result like that;
But when I upload this code to my virtual machine it looks like this;
TL means Turkish Liras. But I don't want to show the currency. I just want numbers.
I also don't want to change the formating of numbers. (Like 257.579,02)
How can I only delete TL in this code?
I would use this:
var cultureWithoutCurrencySymbol =
(CultureInfo)CultureInfo.CurrentCulture.Clone();
cultureWithoutCurrencySymbol.NumberFormat.CurrencySymbol = "";
GridView1.FooterRow.Cells[11].Text =
String.Format(cultureWithoutCurrencySymbol, "{0:c}", sumKV).Trim();
Background:
This will still keep the currency formatting for the current culture, it just removes the currency symbol.
You can save this special culture somewhere, so you don't have to create it every time you need to format your values.
UPDATE:
Now it even compiles... ;-)
Added a Trim(), because there is still a space after the formated number.
Another option is to turn off the currency symbol entirely for the current thread:
private static NumberFormatInfo SetNoCurrencySymbol()
{
CultureInfo culture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
NumberFormatInfo LocalFormat = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone();
NumberFormatInfo ret = culture.NumberFormat;
LocalFormat.CurrencySymbol = "";
culture.NumberFormat = LocalFormat;
// Add the culture to the current thread
Thread.CurrentThread.CurrentCulture = culture;
return ret;
}
That way you will change less code. You can always change it back afterwards:
NumberFormatInfo origNumberFormat = SetNoCurrencySymbol();
string x = String.Format("{0:c}", 55);
CultureInfo.CurrentCulture.NumberFormat = origNumberFormat;
string y = String.Format("{0:c}", 55);
Because you are using String.Format with a format string only, sumKV is formatted according to the UI Culture actually used in your application.
GridView1.FooterRow.Cells[11].Text = String.Format("{0:c}", sumKV),
To get rid with currency symbol, use InvariantCulture in String.Format this way :
String.Format(CultureInfo.InvariantCulture, "{0:c}", sumKV);
If you don't want to show currency then don't use the currency formatting code - {0:c}.
Perhaps try something like the following:
GridView1.FooterRow.Cells[11].Text = String.Format("{0:G}", sumKV);
See this article - String.Format doubles

Categories