One of my development applications has today started displaying American formatted short dates where I am expecting British formatting.
The dates are being rendered using date.ToShortDateString()
I have already checked my Regional settings, keyboard settings, browser settings and web.config. These are all set to English (UK) or not changed. I've also rebooted a number of times.
A mobile version of the same application, running from the same development server, and same website (different web application) is working correctly.
Environment:
Windows 7 64 Bit
Visual Studio 2010 Professional
IIS 7.5
Where else can Regional Settings be changed that might influence display of dates?
The windows regional settings does not affect any website, unless the website is programmed to get the regional settings from the browser preferred languages and apply them to the ASP site
Use the globalization option in the web.config
<globalization culture="es-AR" uiCulture="es" />
OR
Set the value in the global.aspx Application_BeginRequest method
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
Dim lang As String = "es"
If HttpContext.Current.Request.Path.Contains("/en/") Then
lang = "en"
ElseIf HttpContext.Current.Request.Path.Contains("/pt/") Then
lang = "pt"
ElseIf HttpContext.Current.Request.Path.Contains("/es/") Then
lang = "es"
End If
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang)
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(lang)
End Sub
From MSDN
The value of the current DateTime object is formatted using the pattern defined by the DateTimeFormatInfo.ShortDatePattern property associated with the current thread culture. The return value is identical to the value returned by specifying the "d" standard DateTime format string with the ToString(String) method.
Have you tried changing the culture for the current thread? This can be set on a per page basis as well - http://msdn.microsoft.com/en-us/library/bz9tc508%28v=vs.85%29.aspx.
Related
In my web.config file I have this line:
<globalization culture="auto:en-GB" uiCulture="auto:en-GB" requestEncoding="utf-8" responseEncoding="utf-8" responseHeaderEncoding="utf-8"/>
ASP.Net nicely takes care of all date/time formats. Applying the following code in a sample page...
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
txt.Text = New DateTime(2010, 1, 25).ToString()
End Sub
Protected Sub btn_Click(sender As Object, e As EventArgs) Handles btn.Click
Dim dt As DateTime = Convert.ToDateTime(txt.Text.Trim())
Trace.Warn(dt.ToString())
End Sub
With a browser, set to English (UK) I see the date displayed as
25/01/2010 00:00:00
On pressing the button and converting this back to a DateTime value, it works perfectly.
If I change my browser (Chrome) settings to Norwegian Bokmal, and load the page, I see this:
25.01.2010 00.00.00
This again is correct, but, if I then submit the form, ASP.Net crashes:
String was not recognized as a valid DateTime.
Line 9: Dim dt As DateTime = Convert.ToDateTime(txt.Text.Trim())
Why is this happening? Surely if ASP.Net has the sense to display dates based on culture settings, it should be able to read them? I've tried English UK and English US and both work as expected, plus others, so it seems linked to Norwegian in some manner.
Finally found the answer. It is a bug in the .Net framework for v4.0+.
It has been reported in Microsoft Connect, and a temporary workaround is detailed here. Apparently this is problem strictly related to Windows 10:
Windows 10 changes the date and time formatting settings for some
cultures. Of particular concern are seven cultures for three different
regions:
Finnish
Norwegian Bokmål (“Norway” and “Svalbard and Jan Mayen” variants)
Serbian (variants “Cyrillic, Kosovo”, “Latin, Montenegro”, “Latin, Serbia” and “Latin, Kosovo”).
For these seven cultures, Windows 10 changes the date and time
separators to be the same. For example, in Finnish, the standard date
format used to be 26.8.2015 21:08, while it is now 26.8.2015 21.08 –
note the subtle change in the time separator.
In all currently released versions of .NET, the DateTime.Parse method
has a shortcoming: It always fails to parse a date or a date+time
combination in a culture where the date/time separators are the same
character. This bug, together with Windows 10’s culture changes,
breaks the previously hard rule of DateTime.Parse always being able to
parse the culture’s default DateTime representation. Now,
DateTime.Parse(DateTime.Now.ToString()) no longer works under the
described conditions. Neither does
DateTime.Parse(DateTime.Now.ToShortDateString()), which is somewhat
counterintuitive since the changed time separator isn’t even involved,
but true nonetheless – the parser thinks it’s parsing a time instead
of a date.
An official patch will be released in September 2015.
Use the Convert.ToDateTime(string, IFormatProvider) overload to specify the CultureInfo to use.
For background, we are in the process of upgrading to Windows Server 2012 R2, and testing revealed that some date input textboxes on our ASP.NET site aren't working as intended. The textboxes have a CompareValidator defined for them to check if one date is later than the other.
<asp:CompareValidator ID="CompareValidator3" runat="server" ControlToCompare="txtStartDate"
ControlToValidate="txtEndDate" ErrorMessage="..." Operator="GreaterThan" Type="Date"
Display="Dynamic"></asp:CompareValidator>
This CompareValidator is failing all the time now, on Windows Server 2012, whereas the old site hosted on Windows Server 2008 did not have this problem. I have done some digging and I think the most likely culprit is the change in default date format for the Canada region in Windows Server 2012. In the generated code for the page, the DOM element for the validator has a property "dateorder" that's always being set to "ymd". This value is "dmy" on the old site.
...
cutoffyear: "2029"
dataset: DOMStringMap
dateorder: "ymd"
dir: ""
display: "Dynamic"
...
Because our inputs take date strings like "01/01/2015", the "ymd" pattern is not matched and the validator returns false. I have changed the date format settings everywhere that I can think of, and even tried changing the IIS site's .NET Globalization settings to use another culture (en-GB), and nothing has worked. I'm really curious as to where this "ymd" setting comes from, and how to change it. Any help is greatly appreciated. Thanks!
"dateorder" comes from BaseCompareValidator which essentially reads CultureInfo.CurrentCulture
DateTimeFormatInfo dateTimeFormat = CultureInfo.CurrentCulture.DateTimeFormat;
string pattern = dateTimeFormat.ShortDatePattern;
string dateorder = (pattern.StartsWith ("y", true, Helpers.InvariantCulture) ? "ymd" : (pattern.StartsWith ("m", true, Helpers.InvariantCulture) ? "mdy" : "dmy"));
Now the gotcha as pointed here, is that Regional Settings is per-user and you might want to check the account the Application Pool was running under.
Maybe somebody changed the date format in the Windows OS on the old computer? But how about trying to force it within your application...my idea is to do it in the Global.asax file (you may have to add that file to the root of the application if it is not already there). Then, something like this:
using System.Globalization;
using System.Threading;
protected void Application_BeginRequest(Object sender, EventArgs e)
{
CultureInfo myCulture = (CultureInfo) System.Threading.Thread.CurrentThread.CurrentCulture.Clone();
myCulture.DateTimeFormat.ShortDatePattern = "dd-MM-yyyy";
myCulture.DateTimeFormat.DateSeparator = "-";
Thread.CurrentThread.CurrentCulture = myCulture;
}
Have you try to change sort date from control panel regional setting. Dateorder and cutoffyear etc attribute are used by validation JavaScript generated by .net for validator control to function on browser. Value of these comes from server settings. IIS only picks as per server config and generats HTML.
I have a web application that when working in development is fine, but going to Live it does not work.
What the situation is to do with dates. A user enters in a date in the UK format through a text, and I use DateTime.ParseExact(txtDate.Text, "dd-MM-yyyy", Nothing) to tell the date datatype that the date must remain in UK style. As I say, everything is fine in development, but when it goes to Live, it says the that the string is not a valid datetime format.
I have tried Convert.ToDateTime, and all sorts of things, but it just won't work!
Anyone have any suggestions?
I suspect that the culture setting on the live server is different to that of the dev machine.
From the docs:
If provider is a null reference (Nothing in Visual Basic), the current culture is used.
So you need to specify the InvariantCulture try this:
DateTime.ParseExact(datetimeString, "dd/MM/yyyy",
System.Globalization.CultureInfo.InvariantCulture)
My web app is running perfectly in asp vb.net editor. But when i run my web app through IIS7 then i get this error. What am i missing in configuring IIS7? Is there anyone who can suggest something?
Thanks in Advance
Because your IIS7 is configured for the English Language and that date is probably Italian or something similar. You'll have to tell to the Date.Parse which culture to use.
Something like
dateValue = Date.Parse(yourDate, CultureInfo.CreateSpecificCulture("it-IT"))
Or you can change the culture in your IIS7
Here there are the instructions
for example if you use the UI
Using the UI Open IIS Manager and navigate to the level you want to
manage. (omissis)
In Features View, double-click .NET Globalization.
On the .NET Globalization page, in the property sheet, click to select
the global setting you want to edit, and select a value from the
drop-down list.
In the Actions pane, click Apply.
Or you could set the culture of your app in the web.config
<system.web>
<globalization culture="it-IT" uiCulture="it-IT"/>
</system.web>
If you are sure that the date is always in exactly that format, then you can use ParseExact instead:
var date = DateTime.ParseExact(
"31/03/2012",
"dd/MM/yyyy",
System.Globalization.CultureInfo.InvariantCulture);
You can also use the CDate function to parse the date.
Dim dDate As Date = CDate("31/03/2012")
The advantage of using this function over the DateTime parsing functions is that you can feed it any acceptable format of date string and it will convert it. It will throw an error if it can't parse the date.
I need to do a multilingual website, with urls like
www.domain.com/en/home.aspx for english
www.domain.com/es/home.aspx for spanish
In the past, I would set up two virtual directories in IIS, and then detect the URL in global.aspx and change the language according to the URL
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
Dim lang As String
If HttpContext.Current.Request.Path.Contains("/en/") Then
lang = "en"
Else
lang = "es"
End If
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang)
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(lang)
End Sub
The solution is more like a hack. I'm thinking about using Routing for a new website.
Do you know a better or more elegant way to do it?
edit: The question is about the URL handling, not about resources, etc.
I decided to go with the new ASP.net Routing.
Why not urlRewriting? Because I don't want to change the clean URL that routing gives to you.
Here is the code:
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
' Code that runs on application startup
RegisterRoutes(RouteTable.Routes)
End Sub
Public Sub RegisterRoutes(ByVal routes As RouteCollection)
Dim reportRoute As Route
Dim DefaultLang As String = "es"
reportRoute = New Route("{lang}/{page}", New LangRouteHandler)
'* if you want, you can contrain the values
'reportRoute.Constraints = New RouteValueDictionary(New With {.lang = "[a-z]{2}"})
reportRoute.Defaults = New RouteValueDictionary(New With {.lang = DefaultLang, .page = "home"})
routes.Add(reportRoute)
End Sub
Then LangRouteHandler.vb class:
Public Class LangRouteHandler
Implements IRouteHandler
Public Function GetHttpHandler(ByVal requestContext As System.Web.Routing.RequestContext) As System.Web.IHttpHandler _
Implements System.Web.Routing.IRouteHandler.GetHttpHandler
'Fill the context with the route data, just in case some page needs it
For Each value In requestContext.RouteData.Values
HttpContext.Current.Items(value.Key) = value.Value
Next
Dim VirtualPath As String
VirtualPath = "~/" + requestContext.RouteData.Values("page") + ".aspx"
Dim redirectPage As IHttpHandler
redirectPage = BuildManager.CreateInstanceFromVirtualPath(VirtualPath, GetType(Page))
Return redirectPage
End Function
End Class
Finally I use the default.aspx in the root to redirect to the default lang used in the browser list.
Maybe this can be done with the route.Defaults, but don't work inside Visual Studio (maybe it works in the server)
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim DefaultLang As String = "es"
Dim SupportedLangs As String() = {"en", "es"}
Dim BrowserLang As String = Mid(Request.UserLanguages(0).ToString(), 1, 2).ToLower
If SupportedLangs.Contains(BrowserLang) Then DefaultLang = BrowserLang
Response.Redirect(DefaultLang + "/")
End Sub
Some sources:
* Mike Ormond's blog
* Chris Cavanagh’s Blog
* MSDN
Use urlrewriteing.net for asp.net webforms, or routing with mvc. Rewrite www.site.com/en/something.aspx to url: page.aspx?lang=en.
UrlRewriteing.net can be easily configured via regex in web.config. You can also use routing with webforms now, it's probably similar...
with webforms, let every aspx page inherits from BasePage class, which then inherits from Page class.
In BasePage class override "InitializeCulture()" and set culture info to thread, like you described in question.
It's good to do that in this order: 1. check url for Lang param, 2. check cookie, 3. set default lang
For static content (text, pics url) on pages use LocalResources,or Global if content is repeating across site. You can watch videocast on using global/local res. on www.asp.net
Prepare db for multiple languages. But that's another story.
I personnaly use the resources files.
Very efficient, very simple.
UrlRewriting is the way to go.
There is a good article on MSDN on the best ways to do it.
http://msdn.microsoft.com/en-us/library/ms972974.aspx
Kind of a tangent, but I'd actually avoid doing this with different paths unless the different languages are completely content separate from each other.
For Google rank, or for users sharing URLs (one of the big advantages of ‘clean’ URLs), you want the address to stay as constant as possible.
You can find users’ language preferences from their browser settings:
CultureInfo.CurrentUICulture
Then your URL for English or Spanish:
www.domain.com/products/newproduct
Same address for any language, but the user gets the page in their chosen language.
We use this in Canada to provide systems in English and French at the same time.
To do this with URL Routing, refer to this post:
Friendly URLS with URL Routing
Also, watch out new IIS 7.0 - URL Rewriting. Excellent article here http://learn.iis.net/page.aspx/496/iis-url-rewriting-and-aspnet-routing/
I liked this part
Which Option Should You Use?
If you are developing a new ASP.NET Web application that uses either ASP.NET MVC or ASP.NET Dynamic Data technologies, use ASP.NET routing. Your application will benefit from native support for clean URLs, including generation of clean URLs for the links in your Web pages. Note that ASP.NET routing does not support standard Web Forms applications yet, although there are plans to support it in the future.
If you already have a legacy ASP.NET Web application and do not want to change it, use the URL-rewrite module. The URL-rewrite module allows you to translate search-engine-friendly URLs into a format that your application currently uses. Also, it allows you to create redirect rules that can be used to redirect search-engine crawlers to clean URLs.
http://learn.iis.net/page.aspx/496/iis-url-rewriting-and-aspnet-routing/
Thanks,
Maulik.