I can't work out what has changed to only just start getting this error
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
I have checked that the language of the SQL Server instance is "British English"
I have checked that the language of the user is "British English"
What have I missed?
select * from table where updated <= '15/09/2012'
If I run set dateformat dmy, it works, but obviously only at a session level. I need to fix it for the server
A better approach which eliminates all ambiguity is to use ISO 8601 formatting for all your dates - 2012-09-15. And that will work regardless of your regional settings.
select * from table where convert(date,updated,105) <= '15/09/2012'
can you check above query?. I hope it will work.
declare #updated date = GetDate()
select
case when (convert(date,'15/09/2012', 105) <= #updated) then 1
else 2 end
this query is giving 1 as output, so i guess it would work for your case also.
Related
I'm using MS SQL server and I have a date field of type text. The dates stored there are in this format
2017-03-01T18:23:02+0700
I'm trying to convert this field in a datetime field but I fail. I have tried
CONVERT(datetimeoffset,date, 127)
CONVERT(datetime,date, 127)
CONVERT(datetime2,date, 127)
but I keep getting
Conversion failed when converting date and/or time from character
string.
I think the problem is that according to ISO8601 the time offset must be in the format hh:mm while mine is hhmm. I don't mind keeping only the date (yyyy-mm-dd) if it is more easy.
I have read similar question but none matches exactly my case and I can't figure out the solution.
Try this
Declare #dt varchar(50)
set #dt = '2017-03-01T18:23:02+0700'
select convert(datetime, replace(LEFT(#dt, LEN(#dt) - 1), '+', '.'), 126)
If you need only date part then you can use below query
SELECT CAST(LEFT('2017-03-01T18:23:02+0700',10) as DATE)
Use Below query to convert datetime :
SELECT CONVERT(DATETIME,REPLACE(REPLACE('2017-03-01T18:23:02+070','T','
'),'+','.'),103)
For DATE only use below query :
SELECT CONVERT(DATE,REPLACE(REPLACE('2017-03-01T18:23:02+010','T','
'),'+','.'),102)
It doesn't seem to work in both ways (both raise error):
SELECT CONVERT(datetime,'2017-03-01T18:23:02+0700',127)
SELECT CONVERT(datetime,'2017-03-01T18:23:02+07:00',127)
It seems that it works only specifying Z as time zone:
SELECT CONVERT(datetime,'2017-03-01T18:23:02Z',127)
everyone,
On a SQL Server instance running 2012 SP3, the following code returns "1":
SELECT ISDATE('january,25,1999')
However, the following fails the conversion:
SELECT CAST('january,25,1999' AS DATE)
Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.
Am I misunderstanding what ISDATE() ought to return? Why does ISDATE() return a value of "1" for the string? How ought we determine, from SQL Server, whether strings such as "january,25,1999" can be casted as dates?
Thanks!
Forget ISDATE()! You are using SQL Server 2012:
SELECT TRY_CONVERT(date, 'january,25,1999')
This will return NULL if the date cannot be converted -- which I don't think this can be. You can specify a third argument for the particular format you want to convert.
I will note something that in SQL Server 2014:
SELECT TRY_CONVERT(date, 'january,25,1999')
returns an error.
SELECT TRY_CONVERT(datetime, 'january,25,1999')
succeeds.
I have no idea why. But for what you want:
SELECT CONVERT(DATE, TRY_CONVERT(datetime, 'january,25,1999'))
You need to use CONVERT, not CAST, to parse dates from non-standard string formats.
SELECT CONVERT(datetime, 'january,25,1999')
will give you a SQL Server datetime containing 1999-01-25 00:00:00.000
As regards the 2008R2 part...
The issue I found with the ISDATE function is
-- my valid date dd/mm/yy stored as a char
Select ISDATE('dd/mm/yy') returns zero unless you convert to a date
Select ISDATE(convert(date,'dd/mm/yy',103).. say
,but, then as a consequence this returns an error when the convert evaluates a non-date field.
The way around this is to first run
SET DATEFORMAT dmy;
(assume this is scoped to the proc but may not be?)
then ISDATE('dd/mm/yy') should return 1
I can't seem to find an answer to this anywhere --- I want to convert a datetime in SQL to the excel serial number.
I'm essentially looking for the DATEVALUE function from excel but for use in SQL
Any ideas on how to do this? thanks
Assuming the desired date is 2016-05-25
Select DateDiff(DD,'1899-12-30','2016-05-25')
Returns
42515
If you want the time portion as well
Declare #Date datetime = '2016-05-25 20:00'
Select DateDiff(DD,'1899-12-30',#Date)+(DateDiff(SS,cast(#Date as Date),#Date)/86400.0)
Returns
42515.8333333
I ran into this issue and found the most elegant solution to be the following (as others have mentioned, adding the +2 is essential due to the differences between SQL and Excel dates):
Assuming the "Column" is a DateTimeOffset:
SELECT CAST(CAST(COLUMN_TO_BE_CONVERTED as datetime)+2 as float) as EXCEL_DATE_FLOAT
If the column is not already a DateTimeOffset and is just a DateTime, you would not need the double cast; you'd just need something like:
SELECT CAST(COLUMN_TO_BE_CONVERTED+2 as float) as EXCEL_DATE_FLOAT
The resultant float value in either case is what excel recognizes as the date and time and you can easily extract what you need from there. Upon manually verifying the results in excel, I confirmed that the serial numbers matched the date and time exactly as I expected.
You just need to convert your datetime value to int and add 1:
SELECT CONVERT(INT,YourDate) + 1
FROM dbo.SomeTable;
With collation: SQL_Latin1_General_CP1_CI_AS
you should use
Select DateDiff(DD,'18991230','20160525')
Returns
42515
You could replace '20160525' for getdate() or you date field
The code below is validating only date types present in mm/dd/yyyy format and it should not contain time, but how to check a date field's validity in all the possible formats that SQL Server offers?
declare #dateofbirth varchar(max);
declare #dateofbirth_flag bit;
if(ISDATE(#dateofbirth)=1 and #dateofbirth not like '%[:]%')
begin
set #dateofbirth_flag=1;
end
else
begin
set #dateofbirth_flag=0;
end
In general - if ever possible:
You should avoid culture specific date/time literals and better use the appropriate data types!
Your question has no plain answer for all the possible formats that SQL Server offers: A date 01/13/2016 is valid in a mdy culture, but is invalid, if the culture is dmy. Even more dangerous: If the date is 03/05/2016 it is valid, but you will get differing values from there...
In formats without a year like 03/05/08 you'll have pure chaos.
You might extract details with this
select * from sys.syslanguages
What I want to tell: You have to know and you have to specify the culture. Never rely on any implicit casting! Even a checked valid date might be a wrong input...
But you are in luck, since you are using SQL Server 2012. There is the new TRY_PARSE and TRY_CONVERT where you can specifiy the target culture. You will get back a valid date/time or NULL if the cast fails.
On the linked page you'll also find TRY_CONVERT where you can specify a format via style...
Check this apporach with TRY_CONVERT:
declare #dateofbirth varchar(max)='12/13/2016';
declare #dateofbirth_flag bit;
SET #dateofbirth_flag=CASE WHEN TRY_CONVERT(date,#dateofbirth,101) IS NULL THEN 0 ELSE 1 END
SELECT #dateofbirth_flag
--The result: `1` for style `101`
SET #dateofbirth_flag=CASE WHEN TRY_CONVERT(date,#dateofbirth,102) IS NULL THEN 0 ELSE 1 END
SELECT #dateofbirth_flag
--The result: `0` for style `102`
You can use try_convert function for your scenario like this,
In case of variable check
SELECT try_convert(DATE, #dateofbirth)
WHERE try_convert(DATE, #dateofbirth) IS NOT NULL
In case of table
SELECT *
FROM yourtable
WHERE try_convert(DATE, datecolumnname) IS NOT NULL
We've recently migrated our database to a different server and since this I think the date format querying has changed somehow.
Previously we could use the following..
SELECT * FROM table WHERE date > 'YYYY-MM-DD'
However now we have to use..
SELECT * FROM table WHERE date > 'YYYY-DD-MM'
Can someone tell me what I need to change to get back to the previous version?
Try this one -
Query:
SET DATEFORMAT ymd
Read current settings:
DBCC USEROPTIONS
Output:
Set Option Value
-------------------------- -----------------
...
language us_english
dateformat ymd
...
You are right, the date format is different between the servers.
Lots of people fall into the trap of assuming that if you specify a date literal as 'YYYY-MM-DD', it will be interpreted as that regardless of the current date format. This is incorrect. SQL Server sees the 4 digits at the start of the string and correctly deduces that they represent the year. However, it then uses the current date format to tell which way round the month and day are. If you are in the UK, for example, this puts you in an awkward situation because you need a date format of DMY to interpret a date literal like 'DD-MM-YYYY', but a date format of MDY to interpret a date literal like 'YYYY-MM-DD'.
You have several options:
SET DATEFORMAT YMD, and don't let users enter dates any other way.
Use the ODBC date literal syntax {d'YYYY-MM-DD'}. This will be parsed correctly regardless of the current date format. CONVERT(DATE, 'YYYY-MM-DD', 120) has the same effect.
Remove all literal values from your queries and use parameters instead. This is by far the best alternative, and I strongly recommend it.
is you use different formats for the string then you can avoid this behaviour.
There are 2 iso formats that are always specific -- sql server will always parse them in the same way regardless of the server date format setting.
These are:
1) Short form : YYYYMMDD. Example '20120301' -- 1st March 2012
2) Long Form : YYYY-MM-DDTHH:MM:SS.msms'. Example '2012-03-01T12:13:00.000Z' -- 1st March 2012 at 13 minutes past 12 (PM)
In the long form the miliseconds is optional -- this is a perfectly acceptable ISO datetime '2012-03-01T12:13:00Z'
The Z at the end is time zone information. SQL Server doesn't actually require this. (though other products are a bit more exacting)
Try this for example:
DECLARE #foo DATETIME
SET DATEFORMAT DMY
-- this will be the 3rd of january in DMY
SET #foo = '2012-03-01'
SELECT 'DMY: Not ISO', #foo
SET #foo = '20120301'
SELECT 'DMY: ISO', #foo
SET DATEFORMAT MDY
-- this will be the 1st of March in MDY
SET #foo = '2012-03-01'
SELECT 'MDY: not ISO', #foo
SET #foo = '20120301'
SELECT 'MDY: ISO', #foo
When you use text to enter dates you should always try to use one of the two ISO standards. It just makes things much more deterministic.
Short format (SQL Server)
http://msdn.microsoft.com/en-US/library/ms187085(v=sql.90).aspx
ISO 8601 Format (SQL Server)
http://msdn.microsoft.com/en-us/library/ms190977(v=sql.90).aspx
It's a matter of language/culture
Set Language 'us_english'