DateTime ParseExact different behaviour on other server - c#

I have a piece of code that crashes on my test server and not on my development server. I have 2 Windows 2012R2 Servers for dev and test. Both on same patch level, same .NET FrameWork version. Both have the same regional settings (Dutch) for current users and system local. This Dutch setting has the - as the date seperator. The following code snippet works on the dev server but crashes on the test server. I added the snippet with 2 lines of code in a console app and then I can reproducte the error.
The piece of code (simplified for demo console app) is:
string date = "28/02/2017";
DateTime dateDate = DateTime.ParseExact(date, "dd/MM/yyyy", null);
So this works on my dev server and crashed on test
I get this exception
Unhandled Exception: System.FormatException: String was not recognized as a vali
d DateTime.
at System.DateTimeParse.ParseExact(String s, String format, DateTimeFormatInf
o dtfi, DateTimeStyles style)
at System.DateTime.ParseExact(String s, String format, IFormatProvider provid
er)
When I change the code to
string date = "28/02/2017";
DateTime dateDate = DateTime.ParseExact(date, "dd/MM/yyyy", CultureInfo.InvariantCulture);
It works on both servers. When I output the CurrentCultue and CurrentUiCulture in the console app they are the same on both servers.
Any ideas what could go wrong on my test server? When I pass null in the ParseExact method I would expect that the code would also crash on my dev server because the CurrentCulture should then be used and then the date seperator / should cause an error.
Regards
Danny

null specifies that you want to use the current-culture instead, as opposed to passing CultureInfo.InvariantCulture.
MSDN:
If provider is null, the CultureInfo object that corresponds to the
current culture is used.
The / has a special meaning in parsing datetimes. They will be replaced with the currect culture's DateSeparator. (The "/" custom format specifier)
You could also mask them:
DateTime dateDate = DateTime.ParseExact(date, "dd'/'MM'/'yyyy", null);

The / characters is not interpreted literally in date format strings. It is get substituted with date separator according to the used format provider.
You need to enclose the / in single quotes to make it a literal character in the format string:
"dd'/'MM'/'yyyy"

Related

String to DateTime conversion not working

I am converting one string to DateTime variable like this
DateTime selecteddatetest = Convert.ToDateTime("09/21/2017");
This works fine in my production Server, But when I run this code in my local development machine, this throws an error
System.FormatException: 'String was not recognized as a valid DateTime.'
Can anyone please point out what I am missing here?
You could use ParseExact if the time format is consistent:
DateTime.ParseExact("09/21/2017","MM/dd/yyyy",
System.Globalization.CultureInfo.InvariantCulture)
Its probably a localisation issue between the two machines, try specifying the date in the format "2017-09-21" and it should work everywhere.
You are likely using a different culture between the two machines.
For example, the server is using the US culture which expects the format MM/dd/yyyy so your parsing works.
You local machine may be using a culture such as UK which expects the format dd/MM/yyyy and as there is no month 21 it fails.
You can specify the culture explicitly if you know it's always going to be the same:
Convert.ToDateTime("09/21/2017", new System.Globalization.CultureInfo("en-US"));
It may also work with an invariant culture:
Convert.ToDateTime("09/21/2017", System.Globalization.CultureInfo.InvariantCulture);
You may also use ParseExact to specify the desired format:
DateTime.ParseExact("09/21/2017", "MM/dd/yyyy", System.Globalization.CultureInfo.InvariantCulture);

Unable to convert DateTime from SQL Server to C# DateTime

I wrote a program in C# that uses dates. It takes the value from a SQL Server table. I was using Windows 7 and the program worked fine. I had this line of code:
DateTime fechaOperacion = Convert.ToDateTime(reader["FechaOperacion"]);
The reader returned a date in a 24h format and I was able to convert that to a DateTime variable.
Now I did a system upgrade to Windows 10 and that same line of code is throwing the following error:
String was not recognized as a valid DateTime. there is an unknown word starting at index 20.
And now the reader returns a.m. / p.m. format, and at index 20 there is a.m or p.m.
I have tried the following things:
Rephrasing the line of code to:
Convert.ToDateTime(reader["FechaOperacion"], System.Globalization.CultureInfo.InvariantCulture)
reader.GetDateTime(reader.GetOrdinal("FechaOperacion"));
Convert the culture to 24h format
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo(1033);
But none of that seems to work, I don't know what else to do.
Ultimately, the underlying problem here is storing a value that represents a date/time as textual data (meaning, some kind of [n][var]char({max|n}), or at a push: [n]text). This has multiple problems:
it takes more space
it cannot be sorted correctly / efficiently
it cannot be indexed correctly / efficiently
it cannot be filtered correctly / efficiently
it leads to parsing errors between client and server
it has all sorts of localization and internationalization problems
What you should have is a datetime / date / time / etc column. This is then stored as a number (not a string) that requires zero parsing and will work reliably without any conversion problems.
Note: it could be that you are storing it correctly but formatting it inside the select statement of your query. In which case, just don't do that; return the date-time raw, and let the receiving client worry about how to display it.
Depending on your actual format, you can define a suitable format list and do a conversion like below
string[] mfs = { "MM/dd/yyyy HH:mm:ss", "MM/dd/yyyy h:mm:ss tt"};
var dat = DateTime.ParseExact("04/23/1945 8:45:22 PM", mfs,
System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.DateTimeStyles.None);

How to convert given string to a valid datetime of the server?

I am trying to convert a given string which comes from a webservice to datetime. It works on local machine but when I try it from remote server, it gives an error like
"String was not recognized as a valid DateTime.".
Please see the code in below and recommend a general solution for this problem.
DateTime test = DateTime.ParseExact(XmlStringHelper.GetTagValue(result, "date"), "ddMMM", System.Globalization.CultureInfo.InvariantCulture);
Note that, value of the date parameter comes as "13FEB".
Thanks for your helps.
It seems the server is probably running with different culture as you local machine. The result from XmlStringHelper.GetTagValue(result, "date") is probably in an other formatting. Comapare the culture settings and the result of the XmlStringHelper.GetTagValue(result, "date") on both machines.
Your issue is that the date string from the web-service is localized.
Thus, you will have to adopt to the culture of the web-service, like:
DateTime test = DateTime.ParseExact(XmlStringHelper.GetTagValue(result, "date"), "ddMMM",System.Globalization.CultureInfo.*RemoteServerCulture*);

Convert.ToDateTime() error

I get an error trying to convert a string to DateTime, even though this has always worked before.
This is the procedure I used:
Save a datetime to a text file like this:
DateTime.Now.ToUniversalTime().ToString(); //results in something like this 20.9.2015 10.16.12
On application load up:
string s = streamReader.ReadLine(); //the saved string s = "20.09.2015 10.16.12"
DateTime d = Convert.ToDateTime(s);
This results in this:
String was not recognized as a valid DateTime.
I have never experienced this problem before I installed Windows 10 and Visual Studio 2015, my previous setup was Windows 7 and Visual Studio 2013. The weird thing is that this also results in the same error:
DateTime d = Convert.ToDateTime(DateTime.Now.ToUniversalTime().ToString());
This did work perfectly in my previous setup, any ideas why it does not work any more?
Edit: I do believe that this question is not a duplicate of the question Converting a String to DateTime that Thomas Weller linked to. Because this problem is the result of changes in expected behaviour, see the second example. Also I did find a fix to this, but it is not practical:
string s = DateTime.Now.ToUniversalTime().ToString();
s = s.Substring(0, s.IndexOf(" ")).Replace('.', '/') + s.Substring(s.IndexOf(" ")).Replace('.', ':');
DateTime d = Convert.ToDateTime(s);
This probably does not work anymore due to your regional settings on control panel.
To avoid conflicts with regional settings on target enviroment, use DateTime.TryParseExact:
string s = streamReader.ReadLine(); //the saved string s = "20.09.2015 10.16.12"
DateTime d = DateTime.Now;
DateTime.TryParseExact(s, "dd.MM.yyyy HH.mm.ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out d);
Also, if this is your default format and you need this format for entire application, you can set the default culture on your config file.
This code:
Convert.ToDateTime(DateTime.Now.ToUniversalTime().ToString())
Should work on any enviroment, once that DateTime.ToString() and Convert.ToDateTime() without a format provider uses the same DateTimeFormatInfo, unless you are changing your culture between these calls. Note that DateTime.ToString() without format specifier will use General date/time pattern (G), that is based on current culture. And Convert.DateTime without FormatProvider will use current culture too (check these references on MSDN).
My last suggestion is, instead of doing replaces, you can do:
string s = DateTime.Now.ToUniversalTime().ToString("dd/MM/yyyy HH:mm:ss");
I tried following code in console application, and it worked for me. And check .NETFiddle here
string s = "20.09.2015 10.16.12";
DateTime d;
bool isValid = DateTime.TryParseExact(s, "dd.MM.yyyy HH.mm.ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out d);
Try to understand how TryParseExact works. You can read about TryParseExact and formats here. It return a true if it successfully converts the value, else it returns a false.
Please try with this.
CultureInfo objcul = new CultureInfo("en-GB");
DateTime.ParseExact(ValidFrom.Text,"dd/MM/yyyy", objcul);

Convert.ToDateTime Works in console app but errors out in asp.net

Convert.ToDateTime works in console app,
string a = "18/02/2015";
DateTime aa = Convert.ToDateTime(a);
Errors out in asp.net forms saying string is not righ format,
DateTime aa = Convert.ToDateTime(myTextBox.Text);
It used to work before, but since I got a newly installed server it started giving me this error..
Input string seem same to me "18/02/2015"
Convert.ToDateTime uses DateTime.Parse internally, with the current culture of server. And, the problem is your new server's current culture's DateTime format is different from your string.
You can use DateTime.ParseExact() instead of this.
Converts the specified string representation of a date and time to its
DateTime equivalent using the specified format and culture-specific
format information. The format of the string representation must match
the specified format exactly.
DateTime.ParseExact(myTextBox.Text, "dd/MM/yyyy", CultureInfo.InvariantCulture);

Categories