Invalid datetime format exception for Norwegian culture - asp.net

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.

Related

Trouble with Time Formating in Asp.Net

I'm developing a web app which is the transition from a previous desktop versión based in visual basic 6. I have to display times within a support ticket system of when the ticket first arrived,was first handled etc.
I'm running into certain problems when time formating since I seem to have to use several different methods to get what I want depending on the input and now I'm confused as to when I should use each.
For example, when using a system DateNow to get an answer in Hours, minutes and seconds this works fine:
Strings.Format(Date.Now, "HH:mm:ss")
But I have string values within the database, that are stored in a certain way and I cannot modify the database to have a timestamp field which I would prefer to store it, with the time, minutes and seconds scrunched up together as in where 13h,57mins,20secs ends in a string "135720". If I try the same
Dim info as string="135720"
Strings.Format(val(info),"HH:mm:ss)
The answer I get is the actual formating "HH:mm:ss", not the 13:57:20 I expected.
But if I use a transformed VB6 function in .net:
Microsoft.VisualBasic.Format(Val(Info), "##:##:##")
it works just fine.
I also have to use the Microsoft.VisualBasic.Format when trying to fix badly stored strings with partial times such as "1357" or just "135" to turn it into "13:57:00" or "13:50:00"using a case select based on the length of the string.
but I really don't want to be using old programming language in what is supposed to be a an updated app just because I don't finally understand how the new works and I have looked extensively into the documentation, but am none the wiser.
I did look within th comunity but didn't really find the answer either in such questions as:
Is there a way to programmatically convert VB6 Formatting strings to .NET Formatting strings?
A regular expression to validate .NET time format
Time format of datetime field in .net
Time format in asp.net page
Any help finding the new way I should be doing this and why would be greatly apreciated.
Thank You
You can use TimeSpan.
This Function will return a TimeSpan from your String-value.
Public Function GetTimeSpan(s As String)
Dim span As TimeSpan
s = s.Trim 'Trim spaces
'Check if string only contains numbers and if length is valid, else throw exception
If System.Text.RegularExpressions.Regex.IsMatch(s, "^[0-9]+$") AndAlso
s.Length >= 3 AndAlso
s.Length <= 6 Then
s = s.PadRight(6, "0")
Else
Throw New Exception("Invalid String!")
End If
TimeSpan.TryParseExact(s, "hhmmss", Globalization.CultureInfo.InvariantCulture, span)
Return span
End Function
And use it like this:
MessageBox.Show(GetTimeSpan("135700").ToString)
MessageBox.Show(GetTimeSpan("135").ToString)

Date conversion on Live Server issue

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)

ASP.NET Application is displaying american date formats

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.

Trying to retrieve spreadsheet from asp site without any prompts

I have a company site that publishes large reports which I pull down and split up into what I need. I can get the webpage open and get the link to the spreadsheet I need opened, but then I get one IE pop-up for open/save/cancel and, when I click to open the spreadsheet, I get a second pop-up (this one from Excel) saying that the spreadsheet is in a different format than specified by the extension." I have no idea how, if possible, to get the first pop-up to away; the only way I know to normally prevent pop-ups with excel is with DisplayAlerts=False, but adding that doesn't seem to have any effect. The code for the start of this automation project follows:
[EDIT] I have edited and replaced the original coding to reflect the most recent attempt at this. I have managed to get past the first file download pop-up (though with the use of sendkeys) and am now working on getting the second pop-up taken care of (which I suppose is a matter of shifting focus back to excel). Any suggestions on replacing the sendkeys portion are definitely welcomed, as well as advice for returning focus to excel so that I can use excel to control the second pop-up (if that's the best way to do it). The updated code follows:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Sub Automation()
Dim IeApp As Object
Dim IeDoc As Object
Dim URL, URL2 As String
Application.DisplayAlerts = False
URL = "https://companysite.com/directorypage/default.aspx"
URL2 = "https://companysite.com/directorypage/Reports/MyReport.aspx?Format=Excel"
Set IeApp = CreateObject("InternetExplorer.Application")
IeApp.Visible = True
IeApp.Navigate URL
While IeApp.Busy Or IeApp.ReadyState <> 4: DoEvents: Wend
IeApp.Document.All.Item("MainContent_btnAuthenticate").Click
While IeApp.Busy Or IeApp.ReadyState <> 4: DoEvents: Wend
Set IeApp = CreateObject("InternetExplorer.Application")
IeApp.Visible = False
IeApp.Navigate URL2
Do Until thewindow <> 0 'wait for the "File Download" popup window to appear
thewindow = FindWindow(vbNullString, "File Download")
Loop
SendKeys "{LEFT}"
Application.Wait Now + TimeValue("00:00:01")
SendKeys "{LEFT}"
Application.Wait Now + TimeValue("00:00:01")
SendKeys "{ENTER}"
End Sub
You're not going to be able to suppress that message in your code, it's a setting on the user's workstation to prevent harm from malicious files.
The user would have to either edit their Windows registry or have it controlled via a group policy setting. http://support.microsoft.com/kb/948615
I ran across this same issue with Excel documents generated on on the server. The only workaround I made was to create files using the Open XML SDK.
EDIT: I read your question again and noticed it's more focused on the first pop-up, and JMax linked answer (How to disable file download popup in Internet Explorer?) should fix that.
Jon, my two cents on this.
If you have administrative access to your pc then what JMax suggested will sort it out. I would discourage editing the registry if you are an administrator until and unless you know what you are doing.
If it is say an office pc then editing the registry is not even an option. You will have to contact the IT dept. They can either login to your pc as an administrator and then turn the option off for you or they can tweak the GP as zeroef suggested. My best guess is that if it is an office pc then they will login as an administrator and make the changes for you individually instead of making the change in the GP (unless you are the only member of that group). In a corporate environment it is really difficult to get that pulled off via GP as it affects lot of users. There is also a possibility that your request might not be agreed upon if it is an Office pc.
BTW, from what I see, your question has nothing to do with it being an Excel problem :)
HTH
Sid
You could just download the file directly...
Private Declare Function URLDownloadToFile Lib "urlmon" Alias _
"URLDownloadToFileA" (ByVal pCaller As Long, _
ByVal szURL As String, ByVal _
szFileName As String, ByVal dwReserved As Long, _
ByVal lpfnCB As Long) As Long
Sub DownloadFile(sURL, sSaveAs)
Dim rv As Long
rv = URLDownloadToFile(0, sURL, sSaveAs, 0, 0)
If rv <> 0 Then
MsgBox "Error with download!"
End If
End Sub
Don't know if the https will be an issue here.
Another thing to try is just:
Workbooks.Open "https://companysite.com/directorypage/Reports/MyReport.aspx?Format=Excel"

Displaying proper date format depending on culture

I am using a control for a popup calendar date picker. This uses a javascript function, SetText, to set the textbox to the given date. I can't change anything in the calendar control itself but I can override the SetText function. The SetText javascript just takes the TextBox name and the date value in string format and sets the TextBox to the string.
The problem:
I need to display the date in the format "April 30".
Easy to do. Use getMonth() and getDate() where I can parse the information from there.
Now, I need to make sure this shows correctly for different cultures. For example, the UK shows dates as "30 April". Since the code-behind(c#) could be sending the date in the UK format how do I know in the javascript that they're using UK(dd/mm/yyyy) and not US(mm/dd/yyyy)?
The browsers navigator language could be set to one setting while the server is set to another to cause a January 4 as April 1 mismatch.
You are using the Microsoft Ajax Framework, this framework defines a set of "client-side type extensions" which provide added functions or "extensions" to the JavaScript base types.
The Date Type Extensions is what you're looking for, specifically the Date.parseLocale function.
With this function you can parse a string, using a given format.
You can synchronize your server-side and client-side culture by setting the ScriptManager.EnableScriptGlobalization property to true, and use the Date.parseLocale function without specifying any format.
Give a look to this article:
Walkthrough: Globalizing a Date by Using Client Script
See toLocaleString and related functions.
If you control the backend, why not just send a timestamp and push it into Date object?
As for formatting on the client side, since I was already using Dojo, I solved this problem by using dojo.date.locale.format. It was completely painless.
Locale is detected automatically or can be set arbitrarily.
Shorthand format options (e.g.: long short)
Data selectors (e.g.: time, date)
Ability to specify an arbitrary date/time pattern (probably not application to this application, but still useful).
Tutorial: http://docs.dojocampus.org/dojo/date/locale
API doc:
http://api.dojotoolkit.org/jsdoc/1.3/dojo.date.locale.format
Date format descriptions: http://www.unicode.org/reports/tr35/tr35-4.html#Date_Format_Patterns
Three things you could use:
1) toLocaleString - As suggested already. The problem with this is when sending a string of "4/1/2009" this can result in a couple things. January 4 or April 1.
2) navigator.language and navigator.systemLanguage - After you get the date string you can check to see what language the system is in and parse the date from there. The problem with this and solution 1 is what if you have a UK server and the browsers machine is US. You will have the code behind sending April 1 as 1/4/2009 where the javascript will read the string as whatever language the clients browsers is. So, UK server and US browser will give you a wrong result.
3) Use Code Behinds Culture - Create a variable in your javascript that when the page loads, it will call a function in your code behind that returns this.Page.Culture from there, you will know what culture the string is being sent back as. This will eliminate the mismatch that the first two solutions can cause. It will take a little extra work to make sure it's displayed correctly but at least you will be able to use the string without having the possibility of mismatching cultures.
toLocaleDateString would be a better solution than toLocaleString for your problem as it doesn't include the time (as you only are requesting the date).
The open-source JavaScript library Date.js has some great methods for formatting dates, as well as it supports a bunch of languages:
Date.js at Google Code: http://code.google.com/p/datejs/
If you want nicely formatted dates / times, you can just pass a formatting string (nearly identical to those used in .NET Framework) into any Date object's .toString() method.
It also has a whole set of cultures which allow you to simply include the appropriate script for that culture.
If you want to manage that yourself (as we do in our apps), you can find resources which give you the list of appropriate resource strings for a given culture. Here's one that shows proper formatting strings for a ton of cultures: http://www.transactor.com/misc/ranges.html
As you are using ASP.NET then you may also be using ASP.NET Ajax. If so, there are two properties on the ScriptManager that are of use to you:
EnableScriptLocalization - Gets or sets a value that indicates whether the ScriptManager control renders localized versions of script files.
EnableScriptGlobalization - Gets or sets a value that indicates whether the ScriptManager control renders script that supports parsing and formatting of culture-specific information.
<asp:ScriptManager ID="AjaxManager" runat="Server" EnablePartialRendering="true"
EnableScriptGlobalization="true" EnableScriptLocalization="true" />
When you enable both of these (set to true) then ASP.NET Ajax extenders etc. should automatically be localised into the culture specified in web.config:
<configuration>
<system.web>
<globalization
fileEncoding="utf-8"
requestEncoding="utf-8"
responseEncoding="utf-8"
culture="en-GB"
uiCulture="en-GB" />
</system.web>
</configuration>
For instance, setting this will localise the AjaxControlToolkit Calendar into your specificed culture.
Even if you are NOT using ASP.NET Ajax adding a ScriptManager and enabling localisation will give you a useful javascript variable called __cultureInfo that contains a JSON array of localised formate, such as currencies, dates etc.
"CalendarType":1,"Eras":[1],"TwoDigitYearMax":2029,"IsReadOnly":true},"DateSeparator":"/","FirstDayOfWeek":1,"CalendarWeekRule":0,"FullDateTimePattern":"dd MMMM yyyy HH:mm:ss","LongDatePattern":"dd MMMM yyyy","LongTimePattern":"HH:mm:ss","MonthDayPattern":"dd MMMM","PMDesignator":"PM","RFC1123Pattern":"ddd, dd MMM yyyy HH\u0027:\u0027mm\u0027:\u0027ss etc....
I solved this problem by using Datejs as
In codebehind(aspx.cs) I get the culture for an employee and add the appropriate js to the header as
string path =
"http://datejs.googlecode.com/svn/trunk/build/date-"
+ GetCulture() + ".js"; Helper.AddJavaScript(this, path);
(in your case you can get the culture from navigator.systemLanguage (or navigator.browserLanguge etc) and add a script tag to the header with src attribute pointing to the appropriate path)
On the client-side I use
d.toString(Date.CultureInfo.formatPatterns.shortDate)
where d is any date object
(I tried using Date.today().toShortDateString() but it was throwing exception. (the CultureInfo JSON object had a different structure than what the function expects).

Resources