Failed conversion from nvarchar to datetime - sql

I am trying to convert an nvarchar date into a date time, but this error occurs: I have tried multiple ways including CAST and Convert (as code below) with no avail. Any suggestions ?
Date Format : Wed, 19 Jul 2017 16:23:38 +0000
Code:
INSERT INTO feed.article(title,link,sourceID,[date])
SELECT title,link,s.sourceID,
CONVERT(DATETIME,[date],121)
FROM feed.tempXML t
JOIN feed.[source] s ON s.sourceName = t.[source]
Error given:
Conversion failed when converting date and/or time from character string.

If you have MS SQL Server 2012 or higher, you may use TRY_PARSE.
SELECT CAST(TRY_PARSE ('Wed, 19 Jul 2017 16:23:38 +0000' AS datetimeoffset) AS datetime)

I would do this in two parts, one for the date and one for the time:
SELECT title,link,s.sourceID,
(CONVERT(DATETIME, SUBSTRING([date], 5, 10), 106) +
CONVERT(DATETIME, SUBSTRING([date], 18, 8))
)
FROM feed.tempXML t JOIN
feed.[source] s
ON s.sourceName = t.[source];
This minimizes the string operations, so it seems like a pretty simple approach.

EDIT: Check out the solutions by Oleg and Gordon. I actually prefer them both to my own (as it's quite convoluted).
You need to get your date format from this...
'Wed, 19 Jul 2017 16:23:38 +0000'
...to this...
'19 Jul 2017 16:23:38'
You can remove chars from the beginning and end using LEFT and RIGHT. Removing the last 6 from the end would look like this:
LEFT([date], LEN[date] - 6)
We can use the same syntax for our RIGHT() to remove the first 5, but [date] must now be replaced with the entire string from above:
-- RIGHT([date], LEN([date]) - 5) becomes...
RIGHT(LEFT(#d, LEN(#d) - 6), LEN(LEFT(#d, LEN(#d) - 6)) - 5)
All in all, it's ugly, but works:
INSERT INTO feed.article(title,link,sourceID,[date])
SELECT title,link,s.sourceID,
CONVERT(DATETIME,RIGHT(LEFT([date], LEN([date]) - 6), LEN(LEFT([date], LEN([date]) - 6)) - 5),121)
FROM feed.tempXML t
JOIN feed.[source] s ON s.sourceName = t.[source]
IMPORTANT NOTE: This is under the assumption that the format of your date will always have 5 unnecessary characters at the beginning, and that your timezone offset (the +0000 at the end) will always be 0 (so we can simply ignore it).
If you'll have values that make use of the timezone offset, you'll need to account for that.

Based on the format, we should be able make a few "safe assumptions"...
1) The weekday will always be expressed as a 3 char abbreviation.
2) The 3 char abbreviation will be followed by a comma and a space.
3) The portion of code we're interested in will be either 19 or 20 characters.
(10 for single digit dates and 20 for double digit dates)
4) There will be a space following the date.
Based on these assumptions, you should be safe to use the following...
CREATE TABLE #TestData (
StringDate NVARCHAR(40) NOT NULL
);
INSERT #TestData (StringDate) VALUES
(N'Wed, 19 Jul 2017 16:23:38 +0000'),
(N'Wed, 9 Jul 2017 16:23:38 +0000');
SELECT
DateTimeDate = CAST(SUBSTRING(td.StringDate, 6, 20) AS DATETIME)
FROM
#TestData td;

Related

Convert character string into this specific date format?

I am using SQL Server 2014 and I have a table (t1) which contain a column (ReviewDate) in the nvarchar format.
An example of a row of this column is given below:
ReviewDate
Mr John wrote a review in Oct 2017
I need to extract the "date" component from this character string.
To do this, my T-SQL is as follows:
SELECT (RIGHT([ReviewDate], 8)) as [ReviewDate 2]
FROM t1
This gives me "Oct 2017".
Now, I want to convert the "Oct 2017" into "2017-10-01" as a datetime format. This is where I am stuck.
I have tried the following:
SELECT CONVERT(datetime, (RIGHT([ReviewDate], 8)), 121) as [ReviewDate2]
Above syntax gives me the following error message: "Conversion failed when converting date and/or time from character string."
SELECT CAST( (RIGHT([ReviewDate], 8)) as datetime) as [ReviewDate2]
Above syntax gives me the same error message:
Conversion failed when converting date and/or time from character string.
Some help will be appreciated.
All your queries are right but make sure that, it should not have any other string apart from date part.
For example SELECT CAST('x Oct 2017' AS DATE) will give you error like
Conversion failed when converting date and/or time from character
string.
SELECT CAST((RIGHT('Mr John wrote a review in Oct 2017', 8)) as datetime) as [ReviewDate2]
SELECT CAST('Oct 2017' AS DATE)
SELECT CONVERT(DATETIME, 'Oct 2017 ', 121) as [ReviewDate2]
FIDDLE DEMO
so far your sample text is a valid datetime in mssql when I tried to cast. It seems there's some invalid data on your table. try using try_cast() to include those invalid data.
declare #ReviewDate varchar(max)='Mr John wrote a review in Oct 2017'
set #ReviewDate = (RIGHT(#ReviewDate, 8))
select try_cast(#ReviewDate as datetime) as [ReviewDate2]
dbfiddle<>

SQL Server: Extract date from a description column

how can I extract the dates from a description column (nvarchar) like these ones:
'LICENCE SUSPENDED UNTIL DEC 17, 2016 - ABILITY IMPAIRED SUSPENSION NO 5176283'
'SUSPENDED FOR MEDICAL REASONS UNTIL JUNE 19, 2017'
The objective is to insert that date into a datetime column.
I'm using SQL Server v17
Thanks in advance :)
edit: there is always an 'UNTIL' before the unstructured date.
Assuming there is just one date mentioned in nvarchar you need to extract and that it is always "UNTIL" word before that date as you said, you can try PATINDEX and SUBSTRING methods like below:
DECLARE #x nvarchar(MAX) = N'SUSPENDED FOR MEDICAL REASONS UNTIL JUNE 19, 2017'
SELECT CONVERT(Date, substring(#x, patindex('%UNTIL%', #x) + 6, patindex('%[12][0-9][0-9][0-9]%', #x)-2 - patindex('%UNTIL%', #x)), 120)
SET #x ='LICENCE SUSPENDED UNTIL DEC 17, 2016 - ABILITY IMPAIRED SUSPENSION NO 5176283'
SELECT CONVERT(Date, substring(#x, patindex('%UNTIL%', #x) + 6, patindex('%[12][0-9][0-9][0-9]%', #x)-2 - patindex('%UNTIL%', #x)), 120)
If dates are always in the same format and placed after UNTIL:
WITH cte AS (
SELECT 'LICENCE SUSPENDED UNTIL DEC 17, 2016 - ABILITY IMPAIRED SUSPENSION NO 5176283' AS stringValue
UNION ALL SELECT 'SUSPENDED FOR MEDICAL REASONS UNTIL JUNE 19, 2017'
)
SELECT
CAST(SUBSTRING(stringValue, CHARINDEX('UNTIL', stringValue) + 5, CHARINDEX(', 20', cte.stringValue)-18) AS DATE)
FROM cte
-- the output:
2016-12-17
2017-06-19
I used two anchors:
'UNTIL' to get into beginning of the date to parse
', 20' to detect the end of the date
I see a potential problem - months stated in different formats:
DEC and JUNE.. My snippet still can handle this because of anchors, but it is a sign that the format of the string presentation of the date is not the same, therefore extra transformations perhaps required on larger dataset

How to convert “Thu Jun 11 00:49:35 IST 2015” to “YYYY-MM-DD hh:mm:ss” in SQL Server?

How to convert “Thu Jun 11 00:49:35 IST 2015” to “YYYY-MM-DD hh:mm:ss” in SQL Server?
I tried to convert and casting but it's throwing an error
A few things to note about this before I posit a solution:
The source of this information should be modified, if at all possible, to conform to some ISO-standard date.
SQL Server pre-2016 doesn't handle time zone names well, so I'm going to presume that all of your strings contain "IST". If they don't, you'll have to adjust accordingly by searching for them and creating some kind of switch case to modify the resulting datetimeoffset.
I have no idea whether your day representation is two-digit or variable-digit. I've assumed that it's variable, but you can probably simplify this answer with fixed-string parsing if it's two-digit.
Since you have a timezone, the target representation of YYYY-MM-DD hh:mm:ss is ambiguous. I've converted it here to UTC.
If your string is in a table called Dates with column HorribleString, then:
select
convert(varchar(100), convert(datetime2, convert(datetimeoffset,
substring(HorribleString, len(HorribleString) - 3, 4) -- Year
+ substring(HorribleString, 4, len(HorribleString) - 12) -- len(Thu ) + len( IST 2015) = 12
+ case substring(HorribleString, len(HorribleString) - 7, 3) -- Timezone
when 'IST' then ' +05:30'
else ''
end
, 109), 1), 20)
from
Dates

Convert date of format dd mon yyyy to return integer of month in SQL

I have a varchar variable containing value 01 May 2013 and I need to obtain the integer of the Month part.
for eg if 01 May 2013 is input I should get the result as 5
The query I wrote was :
select DATEPART(MM,CONVERT(DATETIME,CONVERT(VARCHAR(15),'01 '+SUBSTRING(FISCAL_MONTH,1,3)+' 2013'),100))
FROM <table name>
Here FISCAL_MONTH is my column name from the table. However this query is showing me the result, for eg 11 for November but is also throwing the following error :
Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.
I have tried various combinations, bit in vain. Kindly note I need it in a query. Kindly help.
If that is the only date you want to convert then you can simplify the SQL statement to:
select datepart(mm,convert(datetime,'01 May 2013'))
I just used this to test and it worked:
declare #t as varchar(333)
set #t = '01 May 2013'
select datepart(mm,convert(datetime, #t))
Gives me
5
If you are still getting that conversion error, then you either have some NULL values OR some date values that are not in the correct format. Check the data in your table to see which it is.
I'll leave it to you to add the rest of the months.
select case substring('01 MAY 2013',4,3) when 'JAN' then 1
when 'FEB' then 2
when 'MAR' then 3
when 'APR' then 4
when 'MAY' then 5
when 'JUN' then 6 else 9999 end
It might just be that there is a 3 instead of a 2 in the substring argument:
SUBSTRING(FISCAL_MONTH,1,2)+' 2013'),100))
The concat might work also:
select DATEPART(MM, CONCAT('01/', substring(convert(varchar(15),'03/23/2013'),1,2),'/2013'));
Wow, it is real interesting to see all the weird code that people come up with. I use the KISS policy most of the time (keep it simple stupid).
How about the MONTH() function. It has been in the TSQL language forever. I even threw in a coalesce to handle any unexpected NULLS.
-- Simple date as text
declare #var_test varchar(20) = '01 may 2013';
-- Use coalesce to handle nulls, use month to return int
select month(coalesce(#var_test, '01 jan 1900')) as my_month_index
Select month ( cast ( date_col as datetime ))
From table
You have to convert with proper format, you have to pass the apprpriate format-style value on your conversion. As per MSDN, you are using "dd mon yy" format, so you have to supply the corresponding format-style-code 6 or 106
Declare #FISCAL_MONTH nvarchar(max) = '01 May 2013'
select datepart(mm,Convert(datetime, #FISCAL_MONTH, 6))
--5
Set #FISCAL_MONTH = '01 November 2013'
select datepart(mm,Convert(datetime, #FISCAL_MONTH, 6))
--11

How to reformat and sort dates stored in nvarchar

I am trying to display Month and YY part of the date column such that it should appear as
Original Format
Apr 12 2009;
Feb 20 2009;
Dec 24 2008;
May 18 2009;
Jan 8 2009;
Dec 6 2008;
Apr 19 2009;
Jan 4 2009;
May 13 2009;
Jan 5 2009
From these dates the day part should be ripped off such that it appears as "Apr 09" and can still be sorted by date such that it appears as:
Dec 08;
Jan 09;
Feb 09;
Mar 09;
Apr 09;
May 09
Thanks,
Sag.
If you want to store the dates as strings in the datbase, you need to use a format that builds on the same principle as the ISO-8601 standard, i.e. you use numerical months and place the most significant value first.
To be textually sortable your values would need to look something like:
08-12, 09-01, 09-02, 09-03, 09-04, 09-05
However, I suggest that you store the dates as datetime values in the database instead, and take care of the formatting when you display the values. That way you can easily sort them in the database (and also do any other processing like getting the difference between two dates).
From a datetime value you can quite easily get the format you want. In .NET for example you use theDate.ToString("MMM yy") to format the date exactly as you want it. As you do the formatting after getting the data from the database it's not a problem that the format is not textually sortable.
You need the LEFT function, and you can sort datetime or smalldatetime in SQL SERVER.
you don't say which database, this is for SQL Server...
try:
declare #x table (datestring nvarchar(30))
insert into #x values ('Feb 20 2009')
insert into #x values ('Dec 24 2008')
insert into #x values ('May 18 2009')
insert into #x values ('Jan 8 2009')
insert into #x values ('Dec 6 2008')
select * from #x
SELECT
LEFT(CONVERT(varchar(30),convert(datetime,datestring),109),3)+' '+SUBSTRING(CONVERT(varchar(30),convert(datetime,datestring),121),3,2)
FROM #x
ORDER BY CONVERT(datetime,datestring)
You should not store dates in strings, it takes more space, and makes it difficult to sort and compare them.