Error converting string to datetime due to locale - sql-server

I'm having a lot of difficulty with locale's in a particular instance of SQL Server 2008 R2 Express.
I'm in the UK and the following fails:
SELECT CAST('2012-12-31' AS DATETIME)
Error message:
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
The Windows server locale is British English. My login locale is British English. Collation 'if that matters' is Latin1_General_CI_AS.
The database 'language' is English (United States) but then this is the same as another instance on a different server and the above SQL doesnt fail.
Any thoughts?

For the user making the database connection -- the SQL user -- set the language to English.
This is a setting specific to the SQL user of the connection issuing the query
One way to check if this is a problem... Run this in Management Studio and login as the SQL user who issues the query
SET LANGUAGE English
SELECT CAST('2012-12-31' AS DATETIME)
If this works, set the default language of the SQL user appropriately

Don't use YYYY-MM-DD for date literals, always use YYYYMMDD. This will never fail, regardless of locale, dateformat settings, language settings, regional settings, etc:
SELECT CAST('20121231' AS DATETIME);
A worthwhile read perhaps:
Bad habits to kick : mis-handling date / range queries

You should explicitly define the date format on your convert, in this case is 120:
SELECT CONVERT(DATETIME,'2012-12-31',120)
You can take a look at this page to see more date formats:
http://msdn.microsoft.com/en-us/library/ms187928.aspx

Related

Default Date Formatting in SQL Server 2017

I am currently debugging a scenario in which dates need to be read from a string in a stored procedure.
The code that we have used is a simple convert statement.
e.g.
SELECT CONVERT(DATETIME, #dateInput)
The problem comes when I need to test the dates coming from the Chinese date format (yyyy.mm.dd) which is ISO 102.
What settings in Windows 10 / SQL Server must be set so that running SELECT CONVERT(DATETIME, '2020.05.16') will not return
"The conversion of a varchar data type to a datetime data type resulted in an out-of-range value."
I understand that using SELECT CONVERT(DATETIME, '2020.05.16', 102) would work but that would make the universal stored procedure incorrect when running with different windows date formats
Along with changing my windows settings to reflect the same date format I also changed:
My default language of my SQLEXPRESS server in Properties > Advanced > Default Language
My default language of my SQL User Login Properties > General > Default Language
This meant that it could read the direct string value without needed the ISO 102 identifier.
If the input value is always in the format yyyy.MM.dd then use the appropriate style code (don't rely on the language setting of the LOGIN):
DECLARE #StringInput varchar(10) = '2020.05.16';
SELECT CONVERT(datetime,#StringInput,102);
Ideally, however, instead of defining your parameter as a varchar define it as a datetime in the first place and have the application pass the correct data type; not a string. But that is a different question for the language your application is written in.

SQL Server Incorrectly Parsing Date

SQL Server 2005
SELECT TOP 10 * FROM abc WHERE aDate = '2014-01-20'
When querying the above in SSMS it would normally return results where aDate is 20 January 2014. However for another user on the same server, it returns a date conversion error and only works when running the following query:
SELECT TOP 10 * FROM abc WHERE aDate = '2014-20-01'
I've checked regional language settings on the local machine and it's exactly the same as mine. Any ideas welcomed.
It is not the regional language settings on the machine that count in this case but the one defined on the database's options.
Anyway, to avoid having to rely on the regional language settings when parsing datetime in queries I would encourage you to use an invariant ISO date format : {d 'yyyy-MM-dd'}. Note there is also one for specifying the hours (ts).
It was account specific, the setting was stored as 'British - English' as opposed to 'English'. Changing this to 'English' resolved the problem. Thank you for your responses.
This error occurred as the SQL server tries parse the date value 20 as month and it causes error as 20 is not a valid month .Always It is good practice to use the date format 'dd-MMM-yyyy' which will work with any type of SQL COLLATION and regional language settings.

Format date of filters and results on SQL Server

I'm in a trouble with the format of dates on my queries.
In SQL Server when I execute the following query:
select *
from users
where register_date >= '2015-03-17'
It throws me a cast conversion error.
But if I do execute the following query:
select *
from users
where register_date >= '2015-17-03'
It returns me the correct data, BUT when I see the the register_date column, it gives me the dates as 'YYYY-MM-DD' format...so it's a little confusing...
How can I configure SQL Server to work always with "YYYY-MM-DD" format, on filters and results?
SQL Server doesn't store a DateTime in any string format - it's stored as an 8 byte numerical value.
The various settings (language, date format) only influence how the DateTime is shown to you in SQL Server Management Studio - or how it is parsed when you attempt to convert a string to a DateTime.
There are many formats supported by SQL Server - see the MSDN Books Online on CAST and CONVERT. Most of those formats are dependent on what settings you have - therefore, these settings might work some times - and sometimes not.
The way to solve this is to use the (slightly adapted) ISO-8601 date format that is supported by SQL Server - this format works always - regardless of your SQL Server language and dateformat settings.
The ISO-8601 format is supported by SQL Server comes in two flavors:
YYYYMMDD for just dates (no time portion); note here: no dashes!, that's very important! YYYY-MM-DD is NOT independent of the dateformat settings in your SQL Server and will NOT work in all situations!
or:
YYYY-MM-DDTHH:MM:SS for dates and times - note here: this format has dashes (but they can be omitted), and a fixed T as delimiter between the date and time portion of your DATETIME.
This is valid for SQL Server 2000 and newer.
If you use SQL Server 2008 or newer and the DATE datatype (only DATE - not DATETIME!), then you can indeed also use the YYYY-MM-DD format and that will work, too, with any settings in your SQL Server.
Don't ask me why this whole topic is so tricky and somewhat confusing - that's just the way it is. But with the YYYYMMDD format, you should be fine for any version of SQL Server and for any language and dateformat setting in your SQL Server.
The recommendation for SQL Server 2008 and newer is to use DATE if you only need the date portion, and DATETIME2(n) when you need both date and time. You should try to start phasing out the DATETIME datatype if ever possible
So in your concrete case - what if you run this query:
select *
from users
where register_date >= '20150317'
Do you get the expected results?
Your Date format in SQL SERVER is 'YYYY-DD-MM' that's why you are getting cast conversion error. For searching you must give the date with this exact format.
But In case of getting result you can use SQL DATE FORMAT and retrieve date in any format e.g
SELECT DATE_FORMAT(users.register_date ,'%Y-%d-%m') AS date FROM users
Result will be : 2015-17-03

Why if I set "default language" in spanish the GETDATE() still formating the date in english?

why if I do this on my SQL-Server 2008:
EXEC sp_configure 'default language', 5
reconfigure
Where the date format is dd/mm/yyyy:
select * from sys.syslanguages where langid = 5
returns
dateformat
----------
dmy
So if I do
select GETDATE()
I'm waiting for something like:
(no column name)
----------------
31/08/2013 13:20:44.590
but I get:
(no column name)
----------------
2013-08-31 13:20:44.590
I'm using SQL-Server 2008 Express compatibility mode 100
ADDED:
My real problem is that I need to pass to Stored Procedures dates in dd/mm/yyyy hh:mm to DATETIME variables, but the parser is still waiting for yyyy-mm-dd although I change the default language.
Thank you
The following is going to be rendered by Management Studio, irrespective of server settings:
SELECT GETDATE();
This is returning a datetime value to the client application, NOT A STRING. If you want a string, you can explicitly convert to a specific style:
As for the input to your stored procedures, please, please, please pass proper datetime parameters and not strings. There is no reason to allow users to enter freetext like 6/9/2013 when you really don't know if they meant September 6th or June 9th. The safe formats to pass to SQL Server are:
YYYYMMDD HH:MM:SS.nnn
YYYY-MM-DDTHH:MM:SS.nnn
Anything else can be misinterpreted. Which is why you shouldn't handle these as strings anywhere except at the final step of presentation / display.
you can use like this
Select CONVERT(varchar(100), GETDATE(),103)+' '
+CONVERT(varchar(100), GETDATE(),108) as now
the result is

CAST failing to create date

I'm getting a cast failure and I can't fathom why.
Here's what is failing :
select cast('16/04/2012' as datetime)
The error is :
"The conversion of a char data type to a datetime data type resulted
in an out-of-range datetime value."
If I use CONVERT with a 103 for format it works without issue as you would expect.
The server is set to british date format, therefore the MSSQL account should also be defaulting to britsh format. It's been rebooted, so it shouldn't be that the service is using a different date format.
This is a SQL2005 instance.
What I really want to know is, what could be causing the CAST to fail?
Use this code:
SELECT convert(datetime, '16/04/2012',105)
Have you tried SET DATEFORMAT DMY?
Date format and datetime format are not necessarily the same. While it may implicitly add the 00:00:00 for hh:mm:ss, maybe try adding that. Type 103 only includes dd/mm/yyyy, so it of course works.
You have a data format as MM:dd:YY, and cast tries to convert you '16/04/2012' which is 'dd/MM/yy' and throws exception because 16 is less then 12 monthes.
You can either change your data format in server settings or use SET DATEFORMAT statement before your query
Are you sure the server is British language format? If I run:
set language british
select cast('16/04/2012' as datetime)
Then I get:
2012-04-16 00:00:00.000
You can check the current session language with
select ##language
The session language defaults from the login in use, assuming it's a SQL Server-provisioned login (i.e. not a Windows user). To check the language for a given user:
select loginproperty('myuser', 'DefaultLanguage')
To make a permanent server change for all newly created logins:
EXEC sp_configure 'default language', 23
reconfigure
...where 23 is the langid obtained via sp_helplanguage.
Always use a language neutral date format - it will always work regardless of any settings:
CAST('YYYYMMDD', AS DATE);
4 digit year, 2 digit month, 2 digit day and NO separators. You will never again have to worry about default language settings.

Resources