SQL Server: Transfer YYYYMMDD-HHMMSS to mm/dd/yyyy hh:mm:ss - sql-server

My SQL Server system is 2016.
As topic, I want to convert YYYYMMDD-HHMMSS to mm/dd/yyyy hh:mm:ss, and use dynamic SQL to fulfill this.
My data looks like this:
ID
20161119-075950
20161117-110952
20161118-153406
The datatype is nvarchar.
While I used the syntax below:
SELECT convert(date,convert(varchar(max),id,130), 130) from abc
An error Conversion failed when converting date and/or time from character string. shows up. I am thinking whether it is because SQL Server cannot identify this YYYYMMDD-HHMMSS as date type, and I need to convert this to YYYYMMDD hh:mm:ss first and then mm/dd/yyyy hh:mm:ss? Feel free to shed some lights. Thanks!

Select CONVERT(VARCHAR(25) , CAST(LEFT(ID , 8) AS DATETIME), 101)
+ ' ' + LEFT(RIGHT(ID , 6) ,2) + ':'
+ SUBSTRING(RIGHT(ID , 6) , 3,2) + ':'
+ RIGHT(ID , 2)
FROM TableName

Try it like this
DECLARE #tbl TABLE(ID NVARCHAR(100));
INSERT INTO #tbl VALUES
('20161119-075950')
,('20161117-110952')
,('20161118-153406');
--This is the actual select you need:
SELECT CAST(LEFT(ID,8) AS DATETIME) + STUFF(STUFF(RIGHT(ID,6),5,0,':'),3,0,':')
FROM #tbl
Your first part is strictly 8 chars long and implicitly casteable (unseperated datetime yyyymmdd). The time part is strictly 6 chars long. I use STUFF to insert the colons. This time can be added to a DATETIME. It will be - again implicitly - casted to DATETIME.
EDIT
To reach the given format you stated in the title just convert the first part first with code 101:
SELECT CONVERT(VARCHAR(10),CAST(LEFT(ID,8) AS DATETIME),101) + ' ' + STUFF(STUFF(RIGHT(ID,6),5,0,':'),3,0,':')
FROM #tbl

This should get the format you want... but there are probably better ways.
select
convert(varchar(16),convert(date,left(ID,8)),101) +
' ' +
substring(substring(ID,10,6),1,2) +
':' +
substring(substring(ID,10,6),3,2) +
':' + substring(substring(ID,10,6),5,2)

Related

SQL Server : How to validate for yyyymmddhhmmss

To avoid any conversion error, we'd like to validate if the target string can be converted to datetime using isdate formula, as follows.
CASE WHEN isdate(#targetstring)= 1 then cast(#targetstring as datetime) else '1900-01-01 00:00:00' end
It's working as expected, it returns 1 when it can be convertible.
select isdate('2021-06-22 23:27:00')
select isdate('20210622')
select isdate('20210622 23:00:00')
But yyyymmddhhmmss can't work as expected, it returns 0, even though the string can be converted to datetime.
select isdate('20210622230000')
If we use this, it seems to work.
select isdate(left('20210622230000', 8) + ' ' + substring('20210622230000', 9,2) + ':' + substring('20210622230000', 11,2) + ':' + substring('20210622230000', 13,2))
If there are any better idea, kindly let me know. Thank you.
Just saying you could trim down string manipulation using STUFF()
Example
Declare #S varchar(50)='20210622232715'
Select try_convert(datetime,stuff(stuff(stuff(#S,13,0,':'),11,0,':'),9,0,' '))
Results
2021-06-22 23:27:15.000

timestamp from sap into datetime in sql

from the beginning. I extracted data from Sap to MYSQL DB. In some tables, there are columns that were extracted as FLOAT and looks like this: 20131009012152.
As you can see it's like the string but float.
If I try to convert it into datetime, I get errors or overload etc.
I have tried CAST, CONVERT, SRT, SUBSTRING, nothing works.
Last try:
SELECT top 10 CREATED_AT,
SUBSTRING(CAST(STR(CREATED_AT, 25, 5) as varchar), 1, 4)
from databank.tablename;
-- wanted to substract parts (here, year) but I get just empty column as result.
Cast to nvarchar to datetime doesn't work. as well as nvarchar- bigint - datetime.
Hope, somebody can help me, thanks
One option, rather ugly, uses the CONVERT function with a series of string concatenations. I first get your numeric timestamp over to a string using a CTE.
WITH cte AS (
SELECT CAST(20131009012152 AS VARCHAR) num
)
SELECT
CONVERT(datetime, SUBSTRING(num, 1, 4) + '-' + SUBSTRING(num, 5, 2) + '-' +
SUBSTRING(num, 7, 2) + ' ' + SUBSTRING(num, 9, 2) + ':' +
SUBSTRING(num, 11, 2) + ':' + SUBSTRING(num, 13, 2), 120) AS the_date
FROM cte;
The verbosity of this query and your data makes me think that you probably did not export properly. Use this only if SAP really has no ability to export a proper timestamp (which I doubt).
Output:
09.10.2013 01:21:52
Demo
Found the similar way that can be directly used in SELECT:
CONVERT(datetime,
SUBSTRING(CAST(STR(COLUMN, 15) as varchar), 1,5) + '-' +
SUBSTRING(CAST(STR(COLUMN, 15) as varchar),6, 2) + '-' +
SUBSTRING(CAST(STR(COLUMN, 15) as varchar), 8, 2) + ' ' +
SUBSTRING(CAST(STR(COLUMN, 15) as varchar),10, 2) + ':' +
SUBSTRING(CAST(STR(COLUMN, 15) as varchar), 12, 2) + ':' +
SUBSTRING(CAST(STR(COLUMN, 15) as varchar), 14, 2), 120) as [COLUMN]
Result: 2017-01-01 15:33:15.000
Besides an old threat I want to share my solution:
Normally the SAP-Timestamps come like this in a char or varchar: 20220620081129
To bring it into a usable SQL format you need to stretch it into a date/datetime
format with dashes and colons.
This can be easily achieved by converting the text into a int/bigint and then
formatting this number into an output format that looks like a date.
Next step is just converting this resulting text into a datetime.
/*Code:*/
convert(datetime,format(convert(bigint,<fieldname>),'##-##-## ##:##:##'),120)
/*Example*/
DECLARE #SAPTable AS TABLE ([/BIC/XCREATE] VARCHAR(30))
INSERT INTO #SAPTable ([/BIC/XCREATE])
VALUES ('20220822144737');
SELECT convert(DATETIME, format(convert(BIGINT, [/BIC/XCREATE]), '##-##-## ##:##:##'), 120)
FROM #SAPTable
As easy as this.
Just adjust the fieldname [/BIC/XCREATE] and the output format to your needs.
In case you have other (shorter or longer) datetime values then, for sure, some things are needed to be adjusted but the principle is the same.
At the end the result is a real date value in terms of the SQL-Server and can be used anyhow.
I think that way it's easier than fiddling with substrings.

Convert Oracle Datetime format query to MS SQL Server Format

I have a Oracle query
SELECT to_timestamp('29-03-17 03:58:34.312000000 PM','DD-MM-RR HH12:MI:SS.FF AM')
FROM DUAL
I want to convert to SQL Server where I need to retain the Oracle date string i.e '29-03-17 03:58:34.312000000 PM':
SELECT
CONVERT(DATETIME, REPLACE(REPLACE('29-03-2017 03:58:34.312000000 PM','-', '/'),'000000 ', ''), 131)
I tried the above query, as 131 format closely matches '29-03-17 03:58:34.312000000 PM' format 'dd/mm/yyyy hh:mi:ss:mmmAM' but only difference is with the year.
In Oracle year is 17 and SQL Server the year is 2017. I need to prefix 20 to the year to make it 2017. This query converts into Hijri datetime. I need it in Gregorian datetime format.
This is the documentation.
https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql
I need to convert the date which is in string in Oracle format to SQL Server equivalent. Is there any way where the format like 'dd/mm/yyyy hh:mi:ss:mmmAM' can be mentioned instead of mentioning the date format code like 131, 101, 102 in the convert function.
You might try it like this:
DECLARE #oracleDT VARCHAR(100)='29-03-17 03:58:34.312000000 PM';
SELECT CAST('<x>' + #oracleDT + '</x>' AS XML).value(N'(/x/text())[1]','datetime');
It seems, that XML is implicitly able to do this correctly...
EDIT: The above is culture related!
It worked on my (german) system, but if you set the correct dateformat you can force this (be aware of side effects for the current job!)
Try this and then remove the -- to try alternative date formats. Or try with GERMAN:
SET LANGUAGE ENGLISH;
SET DATEFORMAT mdy;
--SET DATEFORMAT ymd;
--SET DATEFORMAT dmy;
DECLARE #oracleDT VARCHAR(100)='01-02-03 03:58:34.312000000 PM';
SELECT CAST('<x>' + #oracleDT + '</x>' AS XML).value(N'(/x/text())[1]','datetime');
Another approach
You might split the string in all parts and build a convertible format like this:
DECLARE #oracleDT VARCHAR(100)='29-03-17 03:58:34.312000000 PM';
WITH AllParts(Casted) AS
(
SELECT CAST('<x>' + REPLACE(REPLACE(REPLACE(REPLACE(#oracleDT,'.','-'),' ','-'),':','-'),'-','</x><x>') + '</x>' AS XML)
)
SELECT CONVERT
(DATETIME,
DATENAME(MONTH,'2000'+Casted.value(N'x[2]/text()[1]','nvarchar(max)')+'01') + ' '
+ Casted.value(N'x[1]/text()[1]','nvarchar(max)') + ' '
+ N'20' + Casted.value(N'x[3]/text()[1]','nvarchar(max)') + ' '
+ Casted.value(N'x[4]/text()[1]','nvarchar(max)') + ':'
+ Casted.value(N'x[5]/text()[1]','nvarchar(max)') + ':'
+ Casted.value(N'x[6]/text()[1]','nvarchar(max)') + ':'
+ LEFT(Casted.value(N'x[7]/text()[1]','nvarchar(max)'),3)
+ Casted.value(N'x[8]/text()[1]','nvarchar(max)'),109)
FROM AllParts
Although I don't really understand the need to use a string format that does not suit conversion, but you could divide the string into parts then build it up by adding the parts to each other. The foundation part if the first 8 characters converted to datetime2 using format style 5.
select
t
, convert(varchar, converted ,121) converted
from (
select '29-03-17 03:58:34.312000000 PM' as t
) t
cross apply (
select
convert(datetime2,substring(t,1,8),5) dt2
, case when right(t,2) = 'PM' then convert(smallint,substring(t,10,2)) + 12
else convert(smallint,substring(t,10,2))
end hh
, convert(smallint,substring(t,13,2)) mi
, convert(smallint,substring(t,16,2)) ss
, convert(int,substring(t,19,9)) ns
) ca
cross apply (
select
dateadd(hh,hh,dateadd(mi,mi,dateadd(ss,ss,dateadd(ns,ns,dt2))))
as converted
) ca2
;
Note I am able to use the column aliases of the first cross apply (dt1, hh, mi, ss, ns) in the second cross apply to form the converted datetime2 value.
+--------------------------------+-----------------------------+
| t | converted |
+--------------------------------+-----------------------------+
| 29-03-17 03:58:34.312000000 PM | 2017-03-29 15:58:34.3120000 |
+--------------------------------+-----------------------------+
see: http://rextester.com/DZJ42703

Formatting the SQL query result based on a pattern

I have got a table that contains deferent type of date formats:
########
DateTime
########
10/05/2015
11/05/2015
1/5/2015
01/5/2014
Now my question is that How can I select all the rows based on this pattern \d{2}/\d{2}/\d{4} the format the result with this pattern \d{4}/\d{2}/\{2}?
The first one is dd/mm/yyyy and I would like the result be yyyy/mm/dd
Test Data
DECLARE #TABLE TABLE (Dates VARCHAR(20))
INSERT INTO #TABLE VALUES
('10/05/2015'),
('11/05/2015'),
('1/5/2015'),
('01/5/2014')
Query
The following query will convert all the values to proper sql server date data type.
SELECT CONVERT(DATE,
RIGHT('0000' + PARSENAME(REPLACE(Dates , '/','.'),1),4)
+ RIGHT('00' + PARSENAME(REPLACE(Dates , '/','.'),2),2)
+ RIGHT('00' + PARSENAME(REPLACE(Dates , '/','.'),3),2)
)
FROM #TABLE
Result
2015-05-10
2015-05-11
2015-05-01
2014-05-01
Once you have got the values in well-formatted sql server date type, you can extend the query to get the required output yyyy/mm/dd by doing the following:
SELECT CONVERT(VARCHAR(10),
CONVERT(DATE,
RIGHT('0000' + PARSENAME(REPLACE(Dates , '/','.'),1),4)
+ RIGHT('00' + PARSENAME(REPLACE(Dates , '/','.'),2),2)
+ RIGHT('00' + PARSENAME(REPLACE(Dates , '/','.'),3),2)
), 111)
FROM #TABLE
Result
2015/05/10
2015/05/11
2015/05/01
2014/05/01
In your case I you don't need to use regular expressions. A simple LIKE should suffice.
... WHERE DateTime LIKE "__/__/____" ...

sql-server: Convert Char(14) to Datetime?

With SQL-server 2008 database I have a char(14) data type that I want to convert to a datetime.
Example char(14) values:
20120209102026
20010131120000
The date format is yyyymmdd of some sort.
It seems like the values I posted are not the only format, because I get an "index out of range" error for some of the values. For this I can skip the ones that are not valid dates.
declare #c char(14)
select #c='20120209102026'
Select Cast(Substring(#c,1,8) + ' ' + Substring(#c,9,2)+':'+
Substring(#c,11,2)+':'+ Substring(#c,13,2) as DateTime)
Second Version that ignores out of range numeric values:
Select Cast(
Rtrim(Substring(#c,1,8)
+ Case When len(Substring(#c,9,4))>=4 then +' '+ Substring(#c,9,2) else '' end
+ Case When len(Substring(#c,11,2))=2 then +':'+ Substring(#c,11,2) else '' end
+ Case When len(Substring(#c,13,2))=2 then +':'+ Substring(#c,13,2) else '' end)
as Datetime)
This is ugly but if your format is yyyymmddhhmmss then you can use:
select cast(left(yourDate, 8)+' '+
SUBSTRING(yourDate, 9, 2)+':'+SUBSTRING(yourDate, 11, 2)+':'+RIGHT(yourDate, 2) as datetime)
from yourtable
See SQL Fiddle with Demo
A series of function calls but ends up with the same outcome.
Try like this:
select convert(datetime,STUFF(STUFF(STUFF(STUFF(STUFF('20010131120000',5,0,'/'),8,0,'/'),11,0,' '),14,0,':'),17,0,':'))
Look here for how STUFF works!

Resources