Parsing Date Time string produces unexpected results - c#

I'm trying to convert a string which is in the correct format into a date of exactly the same format for a linq query to work against a SQL date.
I've tried several conversion methods but all have failed. The example below shows the issue:
var test = DateTime.ParseExact("2019-04-09 13:15:00", "yyyy-MM-dd HH:mm:ss", null);
produces
{09/04/2019 13:15:00}
I have no idea why the date comes out like this but I would like to come out like:
2019-04-09 13:15:00
I tried with culture info but no luck. Not sure why this happening?

You have a fundamental misunderstanding of how DateTime values work. They do not have any human-readable format. Rather, they are stored as a binary value that is not human readable. The format you're seeing is something provided as a convenience by your debugger.
If you need a different specific format for anything other than use in SQL*, you can call ToString() with the appropriate format string. Just remember when you do that you are no longer working with a DateTime value, but are back to using a string again, and the best practice is to wait as long as possible before going back to strings.
*For SQL, you should be using parameterized queries, where there is a placeholder in the query and your datetime value is assigned directly to the parameter value without converting to a string first.

You parse the date in the correct format, so that's fine. The DateTime-object contains the correct value, so you can use it for your database.
If you want to see it in your prefered format you also need to output it using the same format, otherwise the default format of your user account (or in case of a web request the preferred language of the calling browser) will be used for displaying it.
Console.WriteLine(test.ToString("yyyy-MM-dd HH:mm:ss"));
If you are using Visual Studio, you can execute this command in the "Immediate Window" while running the debugger:
test.ToString("yyyy-MM-dd HH:mm:ss")
In other windows the debugger will use the default output format like described above.

Related

Why is DateTime.TryParse() returning true for the culture "en-NZ" when MMddyyyy is passed in?

I have the following code:
DateTime.TryParse("06-28-2012", new System.Globalization.CultureInfo("en-NZ"),
System.Globalization.DateTimeStyles.AssumeLocal, out date);
I'm not sure why this is returning true since if I go into my Regional Settings in Windows, I only see the following date formats under short date:
d/MM/yyyy
d/MM/yy
dd/MM/yy
d.MM.yy
yyyy-MM-dd
So then why is a short date format like MM-dd-yyyy returning true? Shouldn't it return false?
I'm using this similar post as a source: DateTime c# parsing
Important:
Please note that I also have my regional settings set to use English (New Zealand) and chose
yyyy-MM-dd as my short date format.
Having your short date format set to yyyy-MM-dd is the cause of this behavior (I do not know if that the standard in New Zealand, but New Zealand's short date is set to d/MM/yyyy on my computer). I do not know if Dot Net, or the underlying Windows APIs are to blame, but it seems like it's smart enough to understand that the 4-digits part represents the year, and after that it just preserves the month-day order (Note that calling DateTime.TryParse("28-06-2012") will actually fail).
You can try using ParseExact, but be warned that will fail on a slightest change of the string (for example, when using a dot or a slash as a separator, instead of a dash.
In my opinion, it's probably best to leave the behavior as is, as it can handle more cases, but if you really must check if a date string was in a specified (yet flexible) format, Regex is the best option. For example Regex.IsMatch("2012/06/28", #"[0-9][0-9][0-9][0-9][./\\][0-9][0-9]?[./\\][0-9][0-9]?"); should suit your needs, while still allowing some flexibility.
You could try DateTime.ParseExact
Could you execute and post the result from the code below?
System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern;
System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.DateSeparator;

Date type in MySql

I'm new to MySQL and C#.
I stored certain values in a column with data type Date. I did not want the time, only the date to be stored.
On viewing these values using phpMyAdmin or MySql command line, I see them in the format:
YYYY-MM-DD
However, when I retrieve these values in to my web application, they are displayed in the following format:
YYYY-MM-DD HH:MM (the time is specifically 12:00).
Why does this happen? And how can I prevent this from happening?
when you store in C# your date field, you use DateTime object. In this object when you don't specify the time part will be put a default value depends on Globalization.
You can study how DateTime works here
You can convert the date to the format you like when you fetch the data, using date_format():
select date_format(datecol, '%Y-%m-%d')
This returns the value as a string.
You shouldn't retrieve the value as a string from mysql. Why? Because if you ever need to do any operations on that value, such as adding a day, then you will need to parse it back into a DateTime again. String parsing can be slow, and when it comes to dates they are prone to errors like misinterpretation of mm/dd/yyyy and dd/mm/yyyy formatting.
The problem you have is that .NET does not have just a Date type. It only has a DateTime type. So loading a MySQL DATE type, is going to get a DateTime with the time portion set to midnight.
There's no direct problem with that, except on how are outputting the result. If you just call .ToString() without any parameters, or you implicitly use it as a string, then you are going to get a result with the full date and time. You simply need to provide a parameter to indicate what formatting you want.
Without any parameters, you are getting the General "G" format. This is explained in the documentation here.
In other words:
yourDateTime.ToString() == yourDateTime.ToString("G")
You can read about all of the other formats available, here and here.
In particular, if you just want the date, then you probably want to do this:
yourDateTime.ToString("d")
Based on your comments, you should be doing this instead:
MySQL Query:
SELECT Gbstartdate FROM TblGbDef
C#:
DateTime gb_start_date = (DateTime) datareader[0];

Convert 2012-06-28T14:30:00-04:00 to yyyyMMddTHHmm format in C#

I want to convert a date in c# like 2012-06-28T14:30:00-04:00 in to "yyyyMMddTHHmm" format both dates are in string.
string currentDate="2012-06-28T14:30:00-04:00";
string requiredDate="yyyyMMddTHHmm"
When i am trying to convert this date with Convert.ToDateTime() then C# return "20120629T0000-04:00" but this is not correct date.
Have a look at the Standard Date and Time Format Strings (MSDN). I guess it might be enough to use just the ToString() method on your DateTime instances.
Possibly you might need to specify CultureInfo (MSDN here) in the appropriate overloads of the convert methods. Possibly the server and client applications are in different cultures and/or timezones.
DateTime.Parse("2012-06-28T14:30:00-04:00").ToString("yyyyMMddTHHmm") produces value you may want.
Note that changing value from absolute ISO8601 format to local ISO8601 format should be done carefully as it changes meaning of the value and often value itself.
Please make sure which of the following options you really want (and adjust code accordingly):
simply drop time from the value. Will produce semi-random time if values are coming from different time-zones.
always move value to a given timezone and make it local to that timezone.
always move value to current timezone and make it local to current timezone
Or maybe you are looking for something else altogether.
I'm not sure this is the format you are trying out
string currentDate="2012-06-28T14:30:00-04:00";
DateTime.Parse(currentDate).ToString("o")
This will give you 2012-06-29T00:00:00.0000000+05:30

time format on my sql server

my c# program selects a datetime field from database and returns the data like the following:
21/06/2012 4:11:48 p.m.
it is not stored this way though (it's stored like 2012/06/21 15:19:10:000).
my locale is set to English/New Zealand
but when I try to save it back to database
the ISDATE() sql function doesn't like that format and just returns NULL. Do I have any options to set the time format in sql or c#? What in sql or c# is making it put "p.m."? (instead of just "PM", which by the way works)
Summing up the problem
See latest related link
You shouldn't be saving it in the database as text at all - you should be using the relevant data type such as DATETIME, and passing DateTime values from .NET to the database using SQL parameters. If you're using the right data type, the value won't actually be stored as "2012/06/21 15:19:10:000" at all. That may be how you see it in SQL Server Studio or something similar, but that doesn't mean it's the raw storage format.
Logically, a date/time doesn't have a format any more than the number ten is "10" (decimal) vs "A" (hex). Avoid string conversions as far as you can, and your life will be easier.
Note: See Jon's response about properly saving the DateTime in the database rather than a string.
For C# String formatting:
The DateTime object can output in different formats using the .ToString() function.
Please see the following links
Custom Date and Time Format Strings
DateTime.ToString Method
So, for example:
DateTime.Now.ToString("dd/MM/yyyy h:mm:ss");
That will output in the format you have in your question.
I think your issue is related to the Set language setting in sql.
Similar to this question: SQL Server ISDATE() Function - Can someone explain this?
Can you try to set your sql language to match your format?
Most of the SQL datetime formats should be recognizable by C# DateTime.Parse(youSQLDatetimeVariable). I find it a bit odd what's happening in your case.
Like other said you really shouldn't but here is how you can convert DateTime to various formats:
SELECT Convert(VARCHAR, MyDateTimeField, 112) from MyTable
That number (112 ) indicates the DateTime format that will appear as Varchar
All formats can be found here in details:
http://anubhavg.wordpress.com/2009/06/11/how-to-format-datetime-date-in-sql-server-2005/
Or within your C# code with
YourDatetimeVariable.ToString("MM-dd-yyyy")
Or whatever format you want within those quotes where MM- month number, dd - day number, yyyy - year.

Formatting String Variables that contain numbers/dates for printing in C#

Maybe it's a n00b question but I've looked at the .net/C# MSDN Library and on this site and have yet to come to a clear answer... say I had For Ex:
(this is not exactly the problem, as I'm not creating the string but reading them out of a DB. But serves to illustrate what I'm working with...)
string dob = "01/02/1990";
dob.ToString("MM/dd/YY"); //however, I can't do this. compiler gives me an error...
likely because it is already a string? How then could I get the string into the format that I want using specifiers, when it's already a string?
I know I could convert it to something else (a DateTime for Ex) and convert back to string using the ToString()...but this seems counter productive... to me at least
I also have several other "kinds" of string variables I'm trying to display into specific formats whilst saving them to a Idictionary for printing into a pdf's fields.
For ex:
d["amount"] = prod.sales.StringAmount; //(here StringSmount holds say 50000 (gotten from a DB), which I want to display as "50,000")
However, I also can't do prod.sales.StringAmount.ToString("N", CultureInfo.CurrentUICulture); cuz it's already a string! Is there an easy way to do this
or need I mess with String Buffers or the StringBuilder class??
thanks!
You can do something like this:
DateTime dob = DateTime.Parse("01/02/1990");
and then
dob.ToString("MM/dd/YY");
will work.
Note that DateTime.Parse() has various options for the possible date-time formats to accept, and that there is also a TryParse() version that returns false if the string is not a valid date - instead than throwing an exception. There are also DateTime.ParseExact() and DateTime.TryParseExact() variations.
Use the same approach for other data types beside date-times: first convert the input string in the correct data type (integer, float etc) - using the various Parse() or TryParse() methods, and then format the result of this conversion.
ToString returns a value without modifying the original.
Instead of
dob.ToString("MM/dd/YY");
use
dob = dob.ToString("MM/dd/YY");
First parse the string into a DateTime instance (via the Parse() or TryParse() methods). On the DateTime Instance you can then call ToString(..).
Using the format provided above, you would need to convert back to DateTime to use the .ToString("MM/dd/YY") format. The reason why is ToString is used to convert an object/value to a string representation and the DateTime object is nice enough to accept a format.
If you want to Format what is already a string, then you should be using String.Format. Visit this link: http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx. This link shows the standard numeric formatters.
You may also want to create your own string format. Look into IFormatProvider and ICustomFormatter: http://msdn.microsoft.com/en-us/library/system.icustomformatter.aspx.
I would recommend first parsing it into a number/DateTime and then using the string formatting variables. For an example of why this can be necessary, consider that your "01/02/1990" string is ambiguous between Jan 2 and Feb 1, unless you parse it using DateTime.ParseExact.
I'd recommend this over 'rolling your own' (e.g. with StringBuilder) so that you can use the built-in culture-sensitive string formatting abilities of .NET.

Categories