Accepted date format changed overnight - sql

Since yesterday I started encountering errors related to date formats in SQL Server 2008.
Up until yesterday the following used to work.
EXEC MyStoredProc '2010-03-15 00:00:00.000'
Since yesterday I started getting out of range errors. After investigating I discovered the date as above is now being interpreted as "the 3rd of the 15th month" which will cause a out of range error.
I have been able to fix this using the following format with the "T".
EXEC MyStoredProc '2010-03-15T00:00:00.000'
By using this format its working fine. Basically all I'm trying to find out is if there is some Hotfix or patch that could have caused this, as all my queries using the first mentioned formats have been working for months.
Also this is not a setting that was changed by someone in the company as this is occurring on all SQL 2005/2008 servers

The language setting of the session can change this.
--This works
set language english
select cast('2010-03-15 00:00:00.000' as datetime)
--This doesn't
set language french
select cast('2010-03-15 00:00:00.000' as datetime)
With the T in between, it always works. If you want a space, then leave out the hyphens.
--This works
set language english
select cast('2010-03-15T00:00:00.000' as datetime)
--This works
set language french
select cast('2010-03-15T00:00:00.000' as datetime)
--This works
set language english
select cast('20100315 00:00:00.000' as datetime)
--This works
set language french
select cast('20100315 00:00:00.000' as datetime)
So my guess is that your app has changed... or some setting on your client computer.

To avoid these kind of problems you should always specify your date format. For your purposes you should use:
SET DATEFORMAT ymd;
See this MSDN page - note the comment that
ydm is not supported for date, datetime2 and datetimeoffset data types
so you might have to use a different format if you're using one of those data types.

It sounds like you've got a mixture of date styles - yyyy/MM/dd vs yyyy/dd/MM - which seem to be reverse UK and US style dates.
If all servers are showing the same behaviour it could be that just the machine executing the code has changed rather than the other machines/SQL servers in the network.
Double check that the date format or indeed culture settings are what you expect them to be on that machine. Assuming they weren't you might be able to find out what changes to the machine were made over the weekend from the event logs or Windows Update history.

Collation can effect dates, as well as the language.
To check what default language a server has installed, use the following SQL command:
sp_configure 'default language'
If the resulting value is 0, the default language U.S. English. If the result is not 0, run the following SQL command to find the installed default language setting and date format used:
select name ,alias, dateformat
from syslanguages
where langid =
(select value from master..sysconfigures
where comment = 'default language')
NOW as to the system updates updates, those were in 2007 to adjust to the DST changes mandated back then.
Machine specific: you CAN set the clock on a specific machine to NOT adjust for DST - check that setting per machine (Windows it is on Control Panel/Date and Time under XP for instance).
IF you choose to use the dashes, you may have issues in dates. If you take out the dashes, SQL Server will never misinterpret the data:
EXEC MyStoredProc '2010-03-15 00:00:00.000'
this is likely getting a time with a negative hour offset, which is in this case invalid.(just a guess)
vs
EXEC MyStoredProc '20100315 00:00:00.000'
Note that the T in there is the ISO8601 format, and thus the dashes are allowed.

Ok I just read a post over at Simons SQL Blog (http://cli.gs/hqaR4) about this specific issue. So one solution to this problem is to Use the new DATETIME2 datatype as it understands languages that doesn't use MDY dates

Related

What is SQL Sever's default format for converting dates from strings

I'm trying to work with a 3rd party application which stores dates (can be entered by the user, in some cases with little validation) in a varchar column, then uses CONVERT( DATETIME, MY_COLUMN ) - without an explicit format - when it wants to use them as dates. Ugh.
Unsurprisingly this often fails. But not always. What is SQL's default format for CONVERT if you don't specify one? It appears to be 101 (i.e. mm/dd/yyyy), but is this always the case? Does it depend on the database or server collation or some other setting? The MSDN CAST and CONVERT docs don't say.
We're using SQL Server 2014.
For the default, it depends on the default language setting at the server or login level, which implicitly sets the dateformat, datefirst, as culture related settings. You can also change the defaults based on login. e.g.
alter login [aucuparia] with default_language=[british];
These can be changed at the session level with set language, set dateformat, and set datefirst.
To see the language setting for the current connection:
select ##language;
To see settings for each language:
select langid, alias, DateFormat, DateFirst, months, shortmonths, days
from sys.syslanguages;

Fetch dates from SQL Server vs PostgreSQL using VDF & MERTECH

I'm currently using a command on PostgreSQL at the beginning of my program to use British date style:
SET DATESTYLE TO ISO, EURO
We are testing SQL Server and I cannot find ANY equivalent function.
dbcc useroptions set language 'British', dateformat dmy;
sp_configure 'default language', 23 reconfigure with override;
SET DATEFORMAT dmy;
These are some of the things I have tested without any luck. While I see the correct values when dbcc useroptions gets queried everything remains the same; YYYYMMDD.
Can anyone point me to the right direction?
If the data type is date then set dateformat etc. does not affect how SQL Server will output it as a date - it's a date, not a string. Notice these all output YYYY-MM-DD:
DECLARE #d DATE = GETDATE();
SET DATEFORMAT DMY;
SELECT #d;
SET DATEFORMAT MDY;
SELECT #d;
SET LANGUAGE BRITISH;
SELECT #d;
SET LANGUAGE US_ENGLISH;
SELECT #d;
These settings affect how strings are interpreted, not how dates are displayed.
The answer - preferred - is to apply such formatting at the client - surely VisualDataFlex has some string formatting functions equivalent to C#'s Format() or ToString() capabilities. But still you should be careful if you want to present users with local, regional formats like d/m/y - they are bound to be misinterpreted by someone. Is 5/7/2014 May 7 or July 5? Depends on the reader.
The workaround - much less desirable - is to muck up your queries with string formatting at the server.
SELECT CONVERT(CHAR(10), col, 103) FROM dbo.tablename;
The problem is NOT # database level. As everyone pointed out the database wont convert the output.
Using Postgres the configuration line is:
datestyle = 'iso, dmy'
This take's care of the issue.
In MSSQL we had to use something else at "driver level", the command is:
SQL_USE_DATAFLEX_FORMAT set to true
And this would take care of the issue. My original question was malformed as I never said what was the main programming language and I apologize for that.
Thanks a lot to everyone as all the answers were right.

Select GetDate() via VB.net different then Select GetDate() via SSMS

When I Use the below code:
Dim cmd As New OdbcCommand("SELECT GETDATE()", oConn)
retVal = cmd.ExecuteScalar()
The resulting output is:
8/1/2013 10:10:39 AM
When I run the exact same query directly in Management Studio I get:
2013-08-01 10:10:39.317
When I check my computer settings versus the SQL Server settings they match.
Anyone know what I need to do to ensure it matches?
Specifically I am talking about the Date format difference.
If you want the date output with a specific string format, then you can use CONVERT() with a style number. For example:
SELECT CONVERT(CHAR(20), GETDATE(), 22),
CONVERT(CHAR(23), GETDATE(), 21);
Results:
-------------------- -----------------------
08/01/13 10:53:54 AM 2013-08-01 10:53:54.943
However, if you are using the date for things other than direct display, only apply that formatting when you are displaying it. For all other purposes it should remain a datetime type and should not be converted to a string.
As for the differences in the actual time value, it's not clear what problem you're talking about, but I suspect you simply ran these queries half an hour apart. If those were run at or around the same time, it looks like the server is half an hour fast - maybe it's in a different time zone or maybe it's just a lot of drift or someone not bothering to use a time service. Your application should never use the time / time zone of the client, especially if it's distributed - always use the time on the server.
Dates have no format. Format comes into play only when you convert dates to a string. The forma used depends on who does the conversion: the server or the client?
Your VB.NET query returns a date from the server and converts it to a string when you write it to the console, a form or whatever. VB.NET uses your programm's CurrentCulture, whose defaults come from the current user's regional settings.
When you display data in SSMS, an ISO format is used so there is no ambiguity when you edit the data.
When you compare date and string values in a query, either explicitly by converting a date to a string or implicitly because you just typed MyDate = '13/1/2013, a conversion is made using the column's collation. Collations are inheritted so the column's collation is the same as the database's collation.
Try this:
net time \\SERVER_NAME
Note: Obviously SERVER_NAME is the name of your SQL Server machine.
Do you see a 30 minute difference in the result of that call?
I looked deeper into the code and found that some enterprising fellow had added code to a line of SQL later in the process which forces DMY format on that query.
so the code in the VB is returning the proper Date on the app machine. Which means that there must be a difference between my computer and the app machine.
Another coder ran into the same issue and so there solution was to add the below code to the SQL that was pulling from the DB.
SET DATEFORMAT dmy
This forces the SQL to use DMY format... I removed this code Compiled and ran the EXE from the server machine and my issue dried up!
Thanks for everyone's help.

SQL Date Format Day and Month Mixup

It seems this question is asked a lot, but none of the answers have given me results. I'm pulling my hair out here ... so hopefully someone has an answer.
I have a production server running SQL Server 2005. I backed up the db and restored it on my laptop's SQL Server Express instance. Now date queries are seriously affected. In the prod. server they are all stored as "4/13/2011 12:00:00 AM" format, but on my laptop they are showing as "2011-04-14 00:00:00.000". When I do a query trying to find entries on "4/14/2011" my laptop gives me the error "The conversion of a varchar data type to a datetime data type resulted in an out-of-range value". Edit: This exact query runs fine on the production SQL server. (I'm using SSMS to run queries ... not an application/code)
I made sure my laptop's Windows regional settings are the same as the server (English(United States)) and everything on the Region and Language control panel is the exact same.
Finally I ran the following two queries:
select name ,alias, dateformat
from syslanguages
where langid =
(select value from master..sysconfigures
where comment = 'default language')
select ##language
Which gave the result of "*us_english, English, mdy*" ..... and "British" respectively. Where is this British coming from?! Now when I run this command before my query (in the management studio)
SET DATEFORMAT mdy
Then everything works perfectly! But in the syslanguages query it seems to already be mdy format. I'm not about to rewrite my application with "SET DATEFORMAT" all over the place - so hopefully someone has a clue. Maybe my SQL Express installation is buggared and I have to reinstall it?
I'm going to keep tinkering to hopefully get this to work.
It is the language settings of the login that you need to change.
You can do it through SSMS -> Security -> Logins -> YourLogin -> Properties -> Default Language
Or through TSQL
ALTER LOGIN [YourLogin] WITH DEFAULT_LANGUAGE=[us_english]
If you specify things in dd-mmm-yyyy format, or better still, use DateTime parameters (rather than varchar input), you won't have a problem.
Try changing the default language to us-english, using the following:
EXEC sp_configure 'default language', 1033
RECONFIGURE
If that doesn't work, you could try language code 0.
Are you passing dates as string literals - or concatenating strings to build up the sql in your application?
If you are doing this, consider using parameters for the dateTime data types. Or at least escape them using the ODBC escape clause and format them as in { ts'yyyy-mm-ddhh:mm:ss[.fff] '} such as: { ts'1998-09-24 10:02:20' }.
It is most probably your application not passing the datetime properly.

How to install SQL Server 2005 Express as NOT US English

Does anyone know how you can get SQL Server 2005 Express to NOT install as US English?
All my win2k8 Regional Settings are set to English(New Zealand) but it always installs as US English.
I can't find anywhere to change it in the installer.
Okay, so date formats are the problem. So you mean your application is trying to insert dates something like this:
insert into Table1 (DateField1) values ('31/3/2008')
which fails because it thinks "31" is the month? Yeah I get that problem too in Australia. Your choices are:
1) Change the default language of the database, and the language for existing users. The language is actually configured on a per-login basis, so for example is SQL Management Studio, Security --> Logins, right-click a login, go to Properties, and change the "Default language" from English to British English. To ensure this also occurs for all new users, you need to change the default language of the server, which is done with:
select * from sys.syslanguages
.... then find the language you're looking for, i.e. British English and note the langid. To set it, say if British English has langid = 23:
sp_configure 'default language', 23
go
reconfigure
go
2) Make your application do date selects/inserts using an appropriate convert i.e.
insert into Table1 (DateField) values (convert(datetime, '31/3/2008', 103))
select DateField1 from Table1 where DateField1 = convert(datetime, '31/3/2008, 103))
3) Make your application do date selects/inserts using an international format. From BOL:
We recommend that you use date-time
formats that are not DATEFORMAT
dependent and are multilanguage. The
ISO 8601 formats,
'1998-02-23T14:23:05' and
'1998-02-23T14:23:05-08:00' are the
only formats that are an international
standard. They are not DATEFORMAT or
default login language dependent and
are multilanguage.
I'm guessing that in this case you can more easily change the database than the application, but if that's not the case then you should really make the application do things in a more global way. App/database design should try to be format-independent where possible.