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];
Related
I have a legacy application where the input is a date string, i.e.:
06/12/2009
The format of the input is always a string, and is consistent, it's always dd/mm/yyyy
At the moment the legacy app just INSERTS this in a DateTime fields. Obviously if the Localization Culture settings of the Server change, we have a bug.
Two questions:
One:
Whats the safest way to store Dates in SQLServer in this situation?
Is there a format that will always be correctly interpreted regardless of the order of day and month?
Two:
What settings exactly determines the culture of a SQLServer DB, is it an OS setting, or a setting of that DB, or what?
cheers
Format YYYY-MM-DD is unambiguous, meaning that SQL Server won't confuse the month
and day when converting a string value to DATETIME. (I've never experienced a problem with an implicit conversion using that format using the four digit year.)
The "safest" (and most convenient) way to store date values in SQL Server is to use DATETIME datatype.
Use the CONVERT function to explicitly specify the input and output formats when converting between DATETIME and strings.
SQL Server 2005 Documentation on CONVERT style argument values:
http://msdn.microsoft.com/en-us/library/ms187928(SQL.90).aspx
To convert a string representation to DATETIME datatype:
select CONVERT(datetime, '2009-06-03', 20)
The first argument is datatype to convert to, the second argument is the expression to be converted, the third argument is the style.
(style 20 is ODBC Canonical format = 'YYYY-MM-DD HH:MI:SS' (24 hour clock)
[FOLLOWUP]
To convert a DATETIME expression (e.g. getdate() to VARCHAR in 'YYYY-MM-DD' format:
select CONVERT(varchar(10), getdate(), 20)
Note that specifying varchar(10) gets you just the first 10 characters of the etnire 'YYYY-MM-DD HH:MM:SS' format.
[/FOLLOWUP]
As to what determines the default formats, that's going to be research. We avoid the issues caused by default formats by specifying the formats.
I would recommend storing all dates in UTC time when they are placed into the database. It will be consistent that way.
Storing dates like this seems to work well...
YYYY-MM-DD
See SET DATEFORMAT. The SQL 'culture' is set by SET LANGUAGE at a session level. SQL Server has its own date format settings, independent of the hosting OS. This is for several reasons: ANSI compliance, to prevent OS changes from affecting applications using the database hosted on that host and not least is compatibility, the SQL long predates the OS is currently running on.
Keep in mind that DATA is not its PRESENTATION. In this case that DATA is a DATE or DATETIME, regardless of how you show them.
As for inserting/updating/comparing datetime values, I quote the BOL:
When specifying dates in comparisons
or for input to INSERT or UPDATE
statements, use constants that are
interpreted the same for all language
settings: ADO, OLE DB, and ODBC
applications should use the ODBC
timestamp, date, and time escape
clauses of:
{ ts 'yyyy-mm-dd
hh:mm:ss[.fff] '} such as: { ts
'1998-09-24 10:02:20' }
{ d 'yyyy-mm-dd'} such as: { d '1998-09-24' }
{ t 'hh:mm:ss'} such as: { t '10:02:20'}
I can assure you that, if you use this formats they will always work, regardless of the locale of you server
I'm a bit conservative in these matters, but I prefer to use separate Year / Month / Day fields in the table, rather than a Date field that uses a DBMS-specific data type. It certainly takes more space, but the lack of ambiguity and increased portability is worth it to me.
The price you pay is that you don't get free date/time arithmetic and sorting, but it's easy enough to do yourself or by a slightly more complex "ORDER BY" clause.
I agree with the advice from spencer7593, but please be aware that using cast or convert without a format can give unexpected results. This T-SQL query returns 12, not 1.
set language British
select month(CAST('2016-01-12' AS datetime))
Normally I prefer to insert as
insert into tbl values('yyyyMMdd')
Then, itll be inserted in proper format based on db.
I am Trying to show a date in a textbox with short format, i get the data from the database.
At presentation Time I want it to be shown with another Format Than this
dd/MM/YYYY HH:mm:ss AM/PM
How can I do it?
Where I want it to be shown:
TextBox1.DataBindings.Clear()
TextBox1.DataBindings.Add("Text", n.ADataSet, "Table.date")
Inside the database it has rhis format:
No, inside the database it will be stored in some binary format. Fundamentally, it's a date - it's not in any particular format, any more than a number is stored in decimal or hex... it's just a date.
When you fetch the value, you're getting a DateTime. Again, that's not got any particular format - it's just a date and time. You need to format it at presentation time.
If you look at the documentation for ControlBindingsCollection you'll see an example with custom formatting.
Try something similar to the below... note that this overload allows you to specify a format ("yyyy-MM-dd") in the last parameter.
textBox1.DataBindings.Add(new System.Windows.Forms.Binding("Text", n.ADataSet, "Table.date", true, System.Windows.Forms.DataSourceUpdateMode.OnValidation, null, "yyyy-MM-dd"));
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.
My C# application have to read some date from MySQL database. Problem I have is that format of date depends on system localisation settings.
My question is if is possible that I always get date in formats yyyy-MM-dd hh:mm:ss, and yyyy-MM-dd, no matter of localisation settings.
Thank you in advance!
If you are storing the dates as true date or datetime values, your application will get the raw binary data back, and it will not be subject to localization until you create a string representation of the date values. My guess is that you are looking at the values in the debugger or using Console.WriteLine(theValue);, which will use the current locale. Always include the desired format and/or the desired culture when converting non-string values to strings.
If you are storing the dates as strings, you will always have to know exactly what format went into the database.
Assuming the dates are stored as date or datetime: just handle the values as they are, and don't convert them to strings until you need to show them to a user:
DateTime theValue = theReader.GetDateTime(fieldOrdinal);
var theValueAsText = theValue.ToString(CultureInfo.InvariantCulture);
var specificTextRepr = theValue.ToString("yyyy-MM-dd HH:mm:ss");
The theValueAsText variable will be a string representation that is not tied to a specific culture. The specificTextRepr will be your specific text representation.
You shouldn't be reading it back as a string from the database - you haven't shown how you're reading the data, but if you use something to populate a DataTable, or LINQ, or IDataReader.GetDateTime then there's no string formatting involved (assuming it's stored properly in the database, which it looks like it is).
A DateTime value doesn't intrinsically have a format, any more than an int is in decimal or hex - it's how you choose to convert it that matters, and you should almost always avoid doing that formatting unless you really need to.
Since you store the dates in date and date/time specific representations, formatting does not play into it at all (as opposed to some highly discouraged storage schemes when date/time is stored as strings, when formatting does matter, but for a wrong reason).
When you query MySQL from your C# code, you will get the correct dates no matter what your locale is. They will be displayed differently based on the locale, but they will represent the proper date regardless of the locale settings.
You can format the date directly in the query by using
date_format(dob,'%d/%m/%Y')
select date_format(dob,'%d/%m/%Y') dob from student where Id=1
Change
CurrentDate = DateTime.Now.ToString("MMM d, yyyy");
CurrentTime = DateTime.Now.ToString("hh:mm tt");
TO
CurrentDate = DateTime.Now.ToString("MMM d, yyyy",CultureInfo.InvariantCulture);
CurrentTime = DateTime.Now.ToString("hh:mm tt", CultureInfo.InvariantCulture);
Hi i am reading a value from a table using SqlDatareader, problem is it is always formatting the value acording to the machine date format settings.
for example the original date format in the source table is saved as
yyyy/mm/dd
when i use SqlDatareader.GetValue in a machine that has date set as MM/dd/YY
it is atutomatically converted to that format
is there anyway to retrive the date value with the original date formatting intact?
thanks
There is no "original date formatting", dates are kept internally as numbers, not strings.
Within a SQL query, you can choose the output formatting with
CONVERT(varchar(30), theColumn, nnn)
where "nnn" is one of the common date formats listed here: MSDN.
Personally I find that page confusing, so another (more useful) page is here: SQL Server Helper. From that page:
CONVERT(VARCHAR(20), GETDATE(), 100)
will return 'Jan 1 2005 1:29PM'
Probably not what you're looking for. But if you want to store the formatted date time, may be you should rather use VARCHAR or CHAR(N) as the field type. I would think the DATETIME field is to store datetime and the format it self isn't that important (or what it is meant for). However, you could reconvert it back to that format in C#.