I've dealt with MS SQL Server datetime types for a long time but never thought why the following is happening:
- I query a table that contains a smalldatetime column. This smalldatetime is always returned in the format
yyyy-MM-dd hh:mm:ss
- Now I write a different query on which I want to apply a smalldatetime filter in the WHERE clause, something like
WHERE TimeStamp >= 'yyyy-MM-dd hh:mm:ss'
- SQL Server retrieves an error and tells me that was not possible to convert that nvarchar to a valid smalldatetime
It appears that it only works if I change the specified format and I write it using the european format, like WHERE TimeStamp >= 'dd-MM-yyyy hh:mm:ss'
.
Why is SQL Server showing me the dates in a format that is not covertable or valid when applied back to itself?
I don't have any problem in changing the date format when writing queries, but I want to play with these dates at an application level (Java-JDBC app) and I don't want to be applying date format changes all the time…
Could anyone explain me why this is happening and if there is any way to solve it at a DB level?
Thanks!!
Edit: Please see the screenshot of the error in Management Studio below.
Best Answer
The only truly safe formats for DATETIME/SMALLDATETIME in SQL Server are:
Anything else is subject to incorrect interpretation by SQL Server, Windows, the provider, the application code, end users, etc. For example, the following always breaks:*
Result:
Just changing the language (which any of your user sessions can do) forced SQL Server to interpret that as
YYYY-DD-MM
instead ofYYYY-MM-DD
. Similar things can happen with setting likeDATEFORMAT
. But these settings are literally ignored when using the above two formats.Always, always, always use one of the above two formats. If you are passing a variable as a string, stop doing that. If you can't, check to make sure it passes
ISDATE()
first. If you are letting people type any date string into a form field, stop doing that, too. Use a date-picker or calendar control and dictate the format of the string before you pass it to SQL Server. Well, depending on the language, just keep it as a datetime value and don't convert it to a string at all.Please read this post:
There is an exception:
SELECT CONVERT(DATE, 'yyyy-mm-dd');
will not break. But I err on the side of consistency rather than using a format only in the one place where I know it doesn't break, and having to use a safer format everywhere else.