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);
Related
My C# winforms program will be used in following countries
United Kingdom : date format day-month-year , currency separator is '.'
United States : date format month-day-year , currency separator is '.'
Denmark : date format day-month-year , currency separator is ','
I want to make the program run properly irrespective of what regional settings are on users computer. My main concern is handling date format and currency fields
(Language translation is not a problem because the program will only show English text)
To do this I have decided that all dates in the database will be saved with yyyy-mm-dd format and all decimal fields will be saved with . as separator.
I created the database with Danish_Norwegian_CI_AS collation .
So I am assuming the data will be saved in the above datetime format & decimal format without me requiring to do anything special.
I have put the following code in my program
var cult = new CultureInfo("en-GB");
Thread.CurrentThread.CurrentCulture = cult;
Thread.CurrentThread.CurrentUICulture = cult;
CultureInfo.DefaultThreadCurrentCulture = cult;
CultureInfo.DefaultThreadCurrentUICulture = cult;
Please help me by telling from your experience if the above code is enough to make my program safe
Culture applies only in the following two scenarios:
Converting a string representation of a value to a native format, which is called "parsing".
Converting the native format of a value to a string representation, which is called "formatting".
When you store a datetime or a decimal or some other type into the database, it is stored in a native format. In a SQL database, this is usually some compact binary value that you will never work with directly.
Consider the following SQL:
declare #dt datetime
set #dt = '01/02/2015 12:34:56'
select #dt
In the first line, we declare a variable of type datetime. It's not a string, it's a specific data type that takes up 8 bytes of memory or disk.
In the second line, we assign a string value to the variable. SQL parses the string, converting it to a datetime so it can be stored in the #dt variable. The actual value stored has a hexadecimal representation of 0x0000A41400CF5940.
When it did the parsing, the current culture for the environment where the code was running was applied. Because I am in the USA, it interpreted the date as January 2nd. If I was in Europe, it would interpret the date as February 1st (changing the internal value to 0x0000A43200CF5940).
Using dates in yyyy-mm-dd format will avoid misinterpretation, but that does not mean that the actual value is stored as a string in that format. It's just that the format is unambiguous, so it will be parsed the same way regardless of culture.
In the third line of code above, we select the variable to include it in a result set. Though we are selecting it in its native form without any conversion, we ultimately see it in a string representation. If you are running the query in a tool such as SQL Server Management Studio, the output window will format the native values to strings so you can read them. When doing so, the current culture is again applied. SQL's default is to show dates in yyyy-mm-dd format, rather than the culture-specific format. But other values, such as decimals, will use the current culture's separator.
If instead of running this in SSMS you actually retrieved the results through your own code in a SqlDataReader (for example), then formatting never occurs. The reader maps SQL's binary native value directly to the appropriate .NET native type, using the mappings shown here. A SQL datetime gets natively mapped to a .NET DateTime.
DateTime dt = (DateTime) reader["dt"];
Now quite often, you see someone doing silly things like this:
DateTime dt = Convert.ToDateTime(reader["dt"].ToString());
This is wasteful because the value is already a DateTime, and this code would use the current culture to format the string, then use it again to parse the string. That's a lot of string manipulation for no reason whatsoever.
Ultimately, in your .NET code, you will end up using that DateTime value and converting it to a string somewhere for output. When you do, that's when you apply the current culture.
Likewise, when you receive an input string from your user (such as when filling out a form), you parse the value to a DateTime using the current culture again.
Native data types are not strings - and are thus not affected by culture.
Notes:
If you want to see the hexadecimal representation of the native binary form of any SQL data type, you can use something like: select convert(varbinary, #dt)
Be aware of whatever the native format is for anywhere you are working. If you're writing to an http stream, a text file, or a document database, etc., the string representation does indeed matter, because a string is the native format in those scenarios.
And just to prove this applies to more than dates, consider:
select 123, 123.45, convert(varbinary, 123), convert(varbinary, 123.45)
--results: 123 123.45 0x0000007B 0x0502000139300000
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];
I have a date that is entered through the system (from a database) as dd/mm/yy I need to programmatically convert the date to en-US format to mm/dd/yyyy so that I can do some date calculations within the code. The code that I have so far is:
String myJames = "25/04/13" // Date String comes in as non-US date
String myJames2 = System.DateTime.Today.ToString(myJames); // I think the problem is here
DateTime d1 = Convert.ToDateTime(myJames2);
DateTime d2 = DateTime.Now;
TimeSpan t = d2 - d1;
double NrOfDays = t.TotalDays;
I know this is not completely correct, especially in the first few lines. Any help getting the dates into one en-US format for effective comparisons would be greatly appreciated.
Just to check I understand your question. You have a date as a string and you want to convert that string into a datetime so you can use it in a calculation? And your problem is that the string isn't in the format that the locale the code is running in would use?
In which case use DateTime.ParseExact.
DateTime d1 = DateTime.ParseExact(myJames,"dd/MM/yy");
This line of code would replace your line declaring and assigning d1. The line assigning to myJames2 can be removed as it isn't needed.
Everytime you convert from or to a string, culturesettings are involved.
So.. if you are converting a DateTime to string, and your culture is en-US, it will automatically converted to: MM/dd/YYYY.
This is also true for converting back. If you convert a string back to a DateTime, the culturesettings are used to see what format the string is in.
Teh culture settings are always: Thread.CurrentThread.CurrentCulture.
Most conversion functions allow to override the format (like "MM/dd/yyyy") and/or the culture. So you can create your own culture and use this during conversions.
You say the database uses dd/MM/yy, but normaly a DateTime in a database is not formatted, it is just a binary value. Or is it stored as a text? If it is stored as a text, than you should ALWAYS convert it to a DateTime using the correct culture or format.
I have a webservice method that gets data from sql of the format
2012-11-18 11:21:03 when i save it to C# string it becomes this format: 18.11.2012 11:21:03
How do i change it back to the SQL format 2012-11-18 11:21:03 ?
Parse it into a dateTime again
DateTime myTime = DateTime.Parse(myString);
and back into a proper to string
myTime.ToString("yyyy-MM-dd HH:mm:ss");
Or just read it into a datetime and cut out the middleman.
You can get the universally sortable string format (which looks like the one used by SQL server) by using the format string "u" like this:
var dateTimeString = String.Format("{0:u}", yourDateTime);
Simply run the below code,
var newDateTime = oldDateTime.Date.ToString("yyyy-MM-dd HH:mm:ss");
Its just converting it back to the SQL Format DATETIME
Trouble with Dates as strings is they are ambiguous and the formats can vary based on where you are in the world, or even local machine settings. You might assume a date string is yyyy-mm-dd but what if it is actually yyyy-dd-mm? Some dates will appear to work and some will be invalid.
In other words is 2013-02-10 the 10th of February or is it the 2nd of October? If it is just a string you have no way of knowing for sure what was intended.
Your best bet as suggested by #Haedrian is to store in a DateTime C# object, not a string. That way it is never ambiguous and you have access to various date specific functions. If you must store as a string you can convert back to a date as above or use
DateTime.TryParse(datestring, out dateVariable);
which won't throw an exception for an invalid format. Depends if you want exceptions!
Also I would suggest if you must use strings to use a 3 character month in strings, which again eliminates the ambiguity, e.g.
"dd-MMM-yy hh:mm tt"
I have a DateTime variable (say, timestamp) that holds a date in its usual format like this:
11/1/2011
This variable is used to build a SQL command. The Oracle database only accepts dates in the format
YYYY-MM-DD
How can I manipulate my variable to store the date in this format?
Don't format the date to include it in SQL at all.
Use a parameterized query, and then just include the value as a parameter. That way you don't have to get any formatting right at all.
You should use parameterized queries for all data - aside from formatting, it also protects you from SQL injection attacks.
Getting a date/time format which works for the particular installation of Oracle you're using right now is not the right fix. Do it properly: avoid including data in your code (the SQL).
On a different matter, your question is making incorrect assumptions to start with. A DateTime variable doesn't hold value in a "usual format" at all, any more than an int holds a decimal representation or a hex representation of a number. DateTime doesn't store text internally at all - it stores a number of ticks. How it is formatted when you call ToString depends on all kinds of cultural aspects. It's worth separating the notion of the fundamental value represented by a type from the formatted string representation you might happen to obtain by calling ToString.
I assume you send the date as string in the SQL command.
DateTime date = ...your object...;
string formattedDate = date.ToString("yyyy-MM-dd");
If it´s in string format, then you need to parse it first. It´s hard to see from your string if it´s day/month/year or month/day/year.
But you could do something like this:
string sDateTime = "11/1/2011";
DateTimeFormatInfo format = new DateTimeFormatInfo();
format.ShortDatePattern = "dd/MM/yyyy"; // or MM/dd/yyyy
DateTime date = DateTime.Parse(sDateTime, format);
string formattedDate = date.ToString("yyyy-MM-dd");
var dt = DateTime.Now;
var formatted = dt.ToString("yyyy-MM-dd");
Try this:
string oracleTimeFomatDate = DateTime.Now.ToString("yyyy-MM-dd")