Convert nvarchar to date time - sql

I have field called event_datetime in my table which is of data type nvarchar
(ex: 2017-04-25-12.09.14.36.089600).
I need to convert it to date time.
Can any one please suggest how to do this?

try Something like this if this helps but i am not sure if you still want the Microsecond part of it :
select CONVERT(datetime2, REPLACE(REPLACE(STUFF('2017-04-25-12.09.14.36',11,1,' '),'-',''),'.',':'))

Here is one way to do it:
DECLARE #S varchar(100) = ' 2017-04-25-12.09.14.36.089600 '
SELECT CAST(
REPLACE(
STUFF(
LEFT(LTRIM(#S), 19)
, 11, 1, 'T')
, '.', ':')
as datetime) As ProperDataType -- just a hint :-)
Result:
ProperDataType
25.04.2017 12:09:14
(live demo on rextester)
Please note that I'm not testing for validity here - anything with a different format, or invalid numbers will raise an error - so if you had a value like this - 2017-14-25-12.09.14.36.089600 it will raise an error.
To do it properly you first need to identify the records that are convertible to dates - and to do that, the easy way is to use a cte and isdate():
;WITH CTE AS
(
SELECT REPLACE(
STUFF(
LEFT(LTRIM(event_datetime), 19)
, 11, 1, 'T')
, '.', ':') As ProperlyFormatted
FROM YourTableName
)
SELECT CAST(ProperlyFormatted as datetime) As event_datetime
FROM CTE
WHERE ISDATE(ProperlyFormatted) = 1
Note that I've used ISO8601 date format, so that you should always get the correct result regardless of your server local settins.

Related

Convert nvarchar date (DD/MM/YYYY) to Date Period (YYYY_MM)

I am trying to convert this into a period format, so e.g. 2018_05 (YYYY_MM). currently the data is in DD/MM/YYYY format.
I tried a cast code but it returns me YYYY_DD.
SELECT
CASE WHEN RESERVED_FIELD_4 IS NULL THEN NULL
ELSE cast(year(RESERVED_FIELD_4) as Nvarchar (4))
+'_'+right('00'+cast(month(RESERVED_FIELD_4) as Nvarchar (2)),2)
END AS [DATAFEED_PERIOD]
I expect/want to see YYYY_MM.
Assuming RESERVED_FIELD_4 is a string type (char/nchar/varchar/nvarchar) the simplest solution would be to use substring:
CASE
WHEN RESERVED_FIELD_4 IS NULL THEN NULL
ELSE SUBSTRING(RESERVED_FIELD_4, 7, 4) + '_'+ SUBSTRING(RESERVED_FIELD_4, 4, 2)
END AS [DATAFEED_PERIOD]
If it's a date/datetime/datetime2 data type, the simplest solution would be to use format:
FORMAT(RESERVED_FIELD_4, 'yyyy_MM')
But for better performance you can use convert and stuff:
SELECT STUFF(CONVERT(char(6), RESERVED_FIELD_4, 112), 5, 0, '_')
In case your format is actually d/m/y the simplest option is to convert to date and than back to string:
SELECT STUFF(CONVERT(char(6), CONVERT(Date, RESERVED_FIELD_4, 103), 112), 5, 0, '_')
This is the common problem of storing a date with a VARCHAR column. You are guessing that the stored pattern is DD/MM/YYYY but the SQL engine doesn't know that and is currently assuming the MM/DD/YYYY pattern.
Please check these results:
-- MM/DD/YYYY
SELECT
DAY ('05/01/2019'), -- 1
MONTH('05/01/2019') -- 5
-- DD/MM/YYYY
SELECT
DAY ('25/05/2019'), -- Conversion failed when converting date and/or time from character string
MONTH('25/05/2019') -- Conversion failed when converting date and/or time from character string.
To display what you want correctly use string functions:
SELECT
RIGHT(RESERVED_FIELD_4, 4) + '_' + SUBSTRING(RESERVED_FIELD_4, 4, 2)
But you should actually fix the values on your VARCHAR column, cast them to DATE and store the values as DATE.
ALTER TABLE YourTable ADD ReservedField4Date DATE
UPDATE YourTable SET
ReservedField4Date = CONVERT(DATE,
RIGHT(RESERVED_FIELD_4, 4) -- Year
+ '-' + SUBSTRING(RESERVED_FIELD_4, 4, 2) -- Month
+ '-' + LEFT(RESERVED_FIELD_4, 2)) -- Day
ALTER TABLE YourTable DROP COLUMN RESERVED_FIELD_4
EXEC sp_rename 'SchemaName.YourTable.ReservedField4Date', 'RESERVED_FIELD_4', 'COLUMN'
Beware that changing the column type might affect other queries that assume this is a VARCHAR column.
If your data is in DD/MM/YYYY format, then it is being stored as a string. Hence, string functions come to mind:
select right(RESERVED_FIELD_4) + '_' + substrint(RESERVED_FIELD_4, 4, 2)
In SQL-SERVER you can use 'format'
format(dy,#your_date) as day_of_year
month(#your_date) as month
Try this:
Select concat(month(#your_date),'_'year(#your_date)) as your_period
this is a reference
Why not just do conversations ? :
SELECT REPLACE(CONVERT(VARCHAR(7), CONVERT(date, RESERVED_FIELD_4, 101), 102), '.', '_')
This assumes RESERVED_FIELD_4 is date type.

SQL - Convert to date

I have a numeric column in SQL which I need to convert to a date. The field is currently coming into the database as: "20181226.00000".
I only need to the characters before the " . ". So i did a SUBSTRING - CHARINDEX looking for anything before the " . " . I then did a cast as NVARCHAR.
Now I'm getting 20181226 but I want this date field to populate like:
"MM/DD/YYYY" .
My current SQL is:
CONVERT(VARCHAR(10),SUBSTRING(CAST('MYFIELD' AS NVARCHAR(50)) ,0, CHARINDEX('.', 'MYFIELD' , 0)),101)
Just change 101 to 103
CONVERT(VARCHAR(10),SUBSTRING(CAST('MYFIELD' AS NVARCHAR(50)) ,0, CHARINDEX('.', 'MYFIELD' , 0)),101)
The easiest way is to convert it to what it actually is, a date, and then back to a varchar using the right style.
SELECT convert(varchar(max), convert(date, substring(convert(varchar(max), nmuloc), 1, charindex('.', convert(varchar(max), nmuloc)) - 1)), 101)
FROM elbat;
I wasn't sure if it's a number or a string. If it's a string you don't need the convert(varchar(max), nmuloc)s.
However a side note: You should not store dates as numbers or strings. Use an appropriate data type like date.
Or you could achieve it like this.
declare #v_value numeric(18,5)=20181226.00000
SELECT SUBSTRING(CAST(CAST(#v_value AS INT) AS VARCHAR),5,2)+'/'+SUBSTRING(CAST(CAST(#v_value AS INT) AS VARCHAR),7,2)+'/'+SUBSTRING(CAST(CAST(#v_value AS INT) AS VARCHAR),1,4) as V_OUTPUT
--Output
/*
V_OUTPUT
------------------
12/26/2018
*/
Best Regards,
Will
First we have convert to varchar and then Date format
SELECT CONVERT(varchar, CAST(CAST('20181206.00000' as VARCHAR(8)) AS DATE), 103); dd/mm/yyyy
SELECT CONVERT(varchar, CAST(CAST('20181206.00000' as VARCHAR(8)) AS DATE), 101); mm/dd/yyyy

SQL Varchar convert to Date - Sybase

I am using Sybase IQ and have the following stored as a varchar:
01October 2010
I want to convert this from varchar to date datatype with the following format:
yyyy-mm-dd eg.2010-10-01
How would I write this SQL statement? Thanks in advance.
With difficulty. There's a reason you should never store dates and times as strings.
It's been awhile since I've used Sybase, but what we need to do is get the field into YYYY-MM-DD format, and then pass it to the DATE() or DATETIME() function.
Let's assume the first two characters are always the day of the month, and the last 4 characters are the year. That means everything in between is the month. Let's also assume that there are no leading or trailing spaces. If either of these assumptions fails, then the query will fail.
Then you can do something like this:
SELECT DATE (
RIGHT(UnnamedField,4) + '-' +
CASE LTRIM(RTRIM(SUBSTRING(Unnamed,3,LEN(Unnamed) - 6)))
WHEN 'January' THEN '01'
WHEN 'February' THEN '02'
WHEN 'March' THEN '03'
.
.
.
WHEN 'December' THEN '12'
END + '-' + LEFT(UnnamedField,2)
)
FROM UnnamedTable
Note that, as others have mentioned, the date data type is not a formatted datatype. If possible you should format it in your application. If you must do it in the query, use the CONVERT() function.
Sybase is able to convert a string to a date. So if you use substring to extract the date into a format that IQ can convert, then you can just use the convert() function.
Here's an example of how to do it:
Sample data:
create table #tmp1 (col1 varchar(100))
insert #tmp1 values ('01October 2010')
Query to convert the value to a date:
select
convert
(
date,
(
substring(col1, 3, charindex(' ', col1) - 2) -- Month
+ substring(col1, 1, 2) -- Day
+ substring(col1, charindex(' ', col1), 5) -- Year (include the leading space)
)
)
from #tmp1
Now that the value is in a date format, you can use the convert function to convert the date datatype to string, using your specified format. The default output for a date datatype is yyyy-mm-dd already.
Edit: After taking a look at #BaconBits' answer, I've realized that I could simplify the query a bit by using the substring function wrappers left, right, and the convert wrapper of date. It's the same logic; but using the simplified wrappers might make it easier to understand.
select
date
(
substring(col1, 3, charindex(' ', col1) - 2) -- Month
+ left(col1, 2) -- Day
+ ' ' + right(col1, 4) -- Year (include the leading space)
)
from #tmp1

Output year and month with a string

Trying to output something like:
2016,11
Using this:
SELECT
CONVERT(VARCHAR(20),YEAR(GETDATE()) + ',' + MONTH(GETDATE())) AS YearMonth
Am I missing something in convert? Because I am getting this error:
Conversion failed when converting the varchar value ',' to data type
int.
Thanks
Try this.
SELECT
CONVERT(VARCHAR(20),YEAR(GETDATE())) + ',' + CONVERT(VARCHAR(20), MONTH(GETDATE())) AS YearMonth
You might use CONVERT with 112 to reach a string without delimiters ("20161110"). Converting this to VARCHAR(*6*) will implicitly cut the day. One (in most cases positiv) side-effect: You will get a low month zero padded (e.g. 2016,04). Then I use STUFF to insert the ,:
SELECT STUFF(CONVERT(VARCHAR(6),GETDATE(),112),5,0,',')
If you do not like the zero padded month, you could replace the 0 in STUFF like this:
DECLARE #d DATETIME={d'2016-04-05'};
SELECT STUFF(CONVERT(VARCHAR(6),#d,112),5,CASE WHEN MONTH(#d)<10 THEN 1 ELSE 0 END,',')
You are missing converting the output of MONTH() to a string. Here is one method:
select datename(year, getdate()) + ',' + cast(month(getdate()) as varchar(255)) as YearMonth
datename() is convenient because it returns a string. Unfortunately, for month it returns the name of the month, rather than the number.
You could also do:
select replace(convert(varchar(7), getdate(), 120), '-', ',')
Or use format() in SQL Server 2012+:
select format(getdate(), 'yyyy,MM')

query to search dates which are stored as string in the database

I have a table where I store an activity completion date as varchar. The format of the date stored is MM/DD/YYYY HH:MM:SS.
I have search window where I have two fields Completion date from and completion date to.The date format selected here is MM/DD/YYYY.
How do I write a query such that I am able to fetch the activity completion between two given dates from the table which has the dates stores as varchar.This table was created a long time back and no thought was given to saving dates as datetime.
You can use SQL CONVERT to change your columns to DATE format but that will cause performance issues.
SELECT *
FROM MyTable
WHERE CONVERT(DATETIME, MyDate) >= CONVERT(DATE, '01/01/2014')
AND CONVERT(DATETIME, MyDate) <= CONVERT(DATE, '01/31/2014')
CONVERT documentation - http://msdn.microsoft.com/en-us/library/ms187928.aspx
if you are unable to change how data is stored, than for better performance , you can create view with calculated column that converts VARCHAR to DATETIME. After that can create index on calculated column. Index on Computed Column documentation
Use the SUBSTRING function to get the date parts in a comparable order (i.e. yyyymmdd):
select *
from mytable
where
CONCAT( SUBSTRING(thedate, 7, 4) , SUBSTRING(thedate, 4, 2) , SUBSTRING(thedate, 1, 2) )
between
CONCAT( SUBSTRING(#FROMDATE, 7, 4) , SUBSTRING(#FROMDATE, 4, 2) , SUBSTRING(#FROMDATE, 1, 2) )
and
CONCAT( SUBSTRING(#TODATE, 7, 4) , SUBSTRING(#TODATE, 4, 2) , SUBSTRING(#TODATE, 1, 2) )
;
You could use this code :
select * from table_name
where CAST(col1 as date )
between CAST(Completion date from as date )
and CAST(Completion date to as date);
Function syntax CAST:
CAST ( expression AS data_type )
You can use below if the date format is {yyyy-MM-dd}, or you can adjust the charindex's index value depending on format
SELECT *
FROM table
WHERE
CHARINDEX('-', col_value, 0) = 5
AND CHARINDEX('-', col_value, 6) = 8
AND LEN(col_value) = 10
The above piece will look for first occurrence of char '-' at position 5 and the second char '-' at position 8 while the entire date value's length is equal to 10 chars
This is not full proof, but will narrow down the search. If you want to add time then just expand the criteria in the where to accommodate the format i.e. {yyyy-MM-dd 00:00:00.000}
This is a safe way to query the data, without any unexpected 'invalid cast / convert' errors.