I have a bunch of dates in varchar like this:
20080107 20090101 20100405 ... How do I convert them to a date format like this:
2008-01-07 2009-01-01 2010-04-05 I've tried using this:
SELECT [FIRST_NAME] ,[MIDDLE_NAME] ,[LAST_NAME] ,cast([GRADUATION_DATE] as date) FROM mydb But get this message:
5Msg 241, Level 16, State 1, Line 2
Conversion failed when converting date and/or time from character string.
5 Answers
The error is happening because you (or whoever designed this table) have a bunch of dates in VARCHAR. Why are you (or whoever designed this table) storing dates as strings? Do you (or whoever designed this table) also store salary and prices and distances as strings?
To find the values that are causing issues (so you (or whoever designed this table) can fix them):
SELECT GRADUATION_DATE FROM mydb WHERE ISDATE(GRADUATION_DATE) = 0; Bet you have at least one row. Fix those values, and then FIX THE TABLE. Or ask whoever designed the table to FIX THE TABLE. Really nicely.
ALTER TABLE mydb ALTER COLUMN GRADUATION_DATE DATE; Now you don't have to worry about the formatting - you can always format as YYYYMMDD or YYYY-MM-DD on the client, or using CONVERT in SQL. When you have a valid date as a string literal, you can use:
SELECT CONVERT(CHAR(10), CONVERT(datetime, '20120101'), 120); ...but this is better done on the client (if at all).
There's a popular term - garbage in, garbage out. You're never going to be able to convert to a date (never mind convert to a string in a specific format) if your data type choice (or the data type choice of whoever designed the table) inherently allows garbage into your table. Please fix it. Or ask whoever designed the table (again, really nicely) to fix it.
8Use SELECT CONVERT(date, '20140327')
In your case,
SELECT [FIRST_NAME], [MIDDLE_NAME], [LAST_NAME], CONVERT(date, [GRADUATION_DATE]) FROM mydb 0In your case it should be:
Select convert(datetime,convert(varchar(10),GRADUATION_DATE,120)) as 'GRADUATION_DATE' from mydb 1I was also facing the same issue where I was receiving the Transaction_Date as YYYYMMDD in bigint format. So I converted it into Datetime format using below query and saved it in new column with datetime format. I hope this will help you as well.
SELECT convert( Datetime, STUFF(STUFF(Transaction_Date, 5, 0, '-'), 8, 0, '-'), 120) As [Transaction_Date_New] FROM mydb Just to add more info about all solution above:
SELECT [FIRST_NAME], [MIDDLE_NAME], [LAST_NAME], CONVERT(date, [GRADUATION_DATE]) FROM mydb Assuming you don't have a WHERE clause, it is ok, the Convert will try to return all dates even if it is not a valid date like '00000000' (it was in my case).
But, if you need a WHERE clause, so you can see a message like this: 
So I tested a mix of some approaches mentioned above like:
DECLARE @DateStart datetime = '2021-02-18' DECLARE @DateEnd datetime = '2021-02-19' SELECT [FIRST_NAME], [MIDDLE_NAME], [LAST_NAME], CONVERT(date, [GRADUATION_DATE]) FROM mydb WHERE --THIS LINE SHOULD BE ENOUGTH TO AVOID WRONG DATES, BUT IT IS NOT ISDATE([GRADUATION_DATE]) = 1 AND CONVERT(char(10), [GRADUATION_DATE], 120) BETWEEN @DateStart and @DateEnd And Finally I used this way with success:
DECLARE @DateStart datetime = '2021-02-18' DECLARE @DateEnd datetime = '2021-02-19' SELECT [FIRST_NAME], [MIDDLE_NAME], [LAST_NAME], CONVERT(date, [GRADUATION_DATE]) FROM mydb WHERE CONVERT(char(10), -- I ADDED THIS LINE TO IGNORE WRONG DATES CASE WHEN ISDATE([GRADUATION_DATE]) = 1 THEN [GRADUATION_DATE] ELSE '1900-01-01' END, 120) BETWEEN @DateStart and @DateEnd