In an ASP.NET application I'm setting the culture to lv-LV. All is fine, but the default short date format seems to be "yyyy.mm.dd". The client wants it to be "dd.mm.yyyy" (which is actually the LV standard). Where does ASP.NET get the date/time settings for a specific culture? How can they be changed for a single culture, without affecting other cultures (the application is supposed to be localizable)?
I once had a similar problem and solved it with:
DateTimeFormatInfo dtfi = (DateTimeFormatInfo)Thread.CurrentThread.CurrentCulture.DateTimeFormat.Clone();
dtfi.ShortDatePattern = "dd.MM.yyyy";
dtfi.DateSeparator = ".";
Thread.CurrentThread.CurrentCulture.DateTimeFormat = dtfi ;
Thread.CurrentThread.CurrentUICulture.DateTimeFormat = dtfi;
That way you get to keep every other regional setting except the date format.
This code actually ran on OnLoad in our Page base class. I'm not so sure that is the best way.
.Net gets the date/time settings for a specific culture from the DateTimeFormatInfo class. You can set the DateTimeFormat property of a CultureInfo with a DateTimeFormatInfo that you have modified. If that culture is the current culture, then you can set it on the CurrentCulture. Either way, this only affects the CultureInfo that you have created and won't affect any other culture. (Any call to CultureInfo.GetCultureInfo("lv-LV") will not pick up those changes either since that is a read-only copy.) You don't necessarily have to pass that CultureInfo to any DateTime formatting methods (ToString, ParseExact) - you can pass the explicit pattern or the DateTimeFormatInfo.
CultureInfo lvLV = new CultureInfo("lv-LV");
DateTimeFormatInfo lvLVdtfi = (DateTimeFormatInfo) lvLV.DateTimeFormat.Clone();
lvLVdtfi.ShortDatePattern = "dd.MM.yyyy";
lvLV.DateTimeFormat = lvLVdtfi;
DateTime.Now.ToString("d", lvLV); // short date pattern from modified lv-LV CultureInfo
DateTime.Now.ToString("d", lvLVdtfi); // short date pattern from modified DateTimeFormatInfo
DateTime.Now.ToString("dd.MM.yyyy"); // explicit short date pattern
If lv-LV is the current Windows culture, then you can set a user override (use intl.cpl the Regional and Language Options control panel and customize the format) and the framework will pick this up.
Related
I am working a multi-lang site. I want to get and set culture and uiculture with culturename without countryname. If browser is english or lang is English choosen, it will return en not en-US or en-GB. Because I use one localresources file per language and I have to send language code to sql procedure as a parameter.
Thread.CurrentThread.CurrentCulture
Thread.CurrentThread.CurrentCulture.Name
Thread.CurrentThread.CurrentUICulture
All of them returns en-GB,de-DE,de-AT etc... I just want first part and use this ones.
http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo%28VS.71%29.aspx
There are the name in the link but browser does note return it, I just want and use the simple part.
How can I do that?
It is solved (:
edit:
Now, How can I read browser's culture and if I don't have it, how can I set the culture that I have.
eg: I have en,de,ru and the visitor's browser sen me fr, I want it is shown en ?
Have a look at the TwoLetterISOLanguageName-property. It should return the identifier you are looking for. For example:
var cult = new System.Globalization.CultureInfo("en-US").TwoLetterISOLanguageName;
Returns "en" so that you can send it to the stored procedures.
I would like to ask if it is a good coding practice to manually set the YearMonthPattern of the CurrentCulture? My problem is I set the current culture to Invariant, and the YearMonthPattern changed.
What I did is just added the code to set the YearMonthPattern just after setting the Cultures.
//Set Cultures
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(127);
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(127);
//Set Year Month Pattern
System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.YearMonthPattern = "MMMM, yyyy";
I can't see anything wrong with it. It's just that it might not be conform to the actual culture pattern but if that's how you want years to be displayed it is OK.
In my ASP.MVC 2.0 website I have the following setting in web.config:
<globalization uiCulture="da-DK" culture="en-US" />
When I try to display an amount in a view using Html.DisplayFor() or ToString("C2") I expected to get "kr. 3.500,00" (uiCulture) and not "$3,500.00" (culture).
<%:Html.DisplayFor(posting => posting.Amount)%>
<%:Model.Amount.ToString("C2")%>
If I explicit uses CurrentUICulture info it works as expected, but I don't want to do that everytime I need to display a number, date or decimal. And I also like to use DisplayFor, which doesn't support the IFormatProvider parameter.
<%:Model.Amount.ToString("C2", System.Globalization.CultureInfo.CurrentUICulture)%>
How can I change the formatting, without changing the culture of the system?
This is running in Azure, and if I change the culture to "da-DK" all decimal points are lost, when saving to Azure Table storage! #BUG
The UI culture is used to lookup and load resources, the Culture is used for formatting.
So the various ToString(string) and String.Format overloads that don't take a culture will use the thread's current Culture (System.Globalization.CultureInfo.CurrentCulture) to format.
If you want to use Danish formatting for currency, dates, ... then Thread.CurerentThread.CurrentCulture needs to be set to CultureInfo.GetCultureInfo("da-DK") (directly or indirectly).
Summary: you have Culture and UI Culture the wrong way around.
I am writing extensions to a web app that doesn't need to be localized. As the company grows I believe there is a possibility that there may be some effort in the future to do this localization.
Mindful of that I would like to mark all of the place that I am using country-specific date formats in an attribute on the method, for example:
For Each exception As String In exceptionDates
Dim DateBits() As String = exception.Split("/")
dates.Add(New Date(Integer.Parse(DateBits(2)) _
, Integer.Parse(DateBits(0)) _
, Integer.Parse(DateBits(1))))
Next
Any suggestions on either what attribute to use, a generic attribute, or some other mechanism (other that putting a funky comment in the code 'NOTLOCALIZEDMOFO!). .NET 3.5 mixed language app.
Pass CultureInfo.InvariantCulture where possible.
In particular, you should replace that code with dates.Add(DateTime.ParseExact(exceptions, "M/d/yyyy", CultureInfo.InvariantCulture));
I'm developing a shopping cart, and part of the functionality is to select your currency.
I have a drop down list, and when the selected index changes I've written some code to find the culture code (such as en-GB or en-US) and then change the culture of the current session. In addition, using the exchange rates given it changes the price...
I currently have en-GB as the default culture. When someone selects the en-US culture from the drop down everything works fine. The currency changes (all currency labels are set with ToString("C")) and the exchange rate changes.
When I use the drop down list to select en-GB again, the exchange rate changes (so I know the code is working), and after debugging I can see that the culture session has changed from en-US to en-GB, but the currency still displays as $ and not £.
I really can't understand why this is happening. The code is very simple, I'm overriding the page_Load event for each page to display the correct currency based on culture:
protected override void OnLoad(EventArgs e)
{
if (Session["Culture"] != null)
{
string culture = Session["Culture"].ToString();
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(Session["Culture"].ToString());
}
base.OnLoad(e);
}
Why does it not change the currency back to £ when I'm changing the session culture from en-US to en-GB?
Because you are checking if (Session["Culture"] != null), which restricts you to set the culture second time as Session["Culture"] will not be null.
I got it, because it was coming from a database entry that for some reason was a char(10) datatype, I forgot to trim the text. This resulted in the culture not being found by the Framework and defaulting back to en-US as it couldn't find 'en-GB '.