SQL Server : How to validate for yyyymmddhhmmss - sql-server

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

Related

T-SQL Convert String to Time for DATEDIFF() Calculation

I am having a problem converting a string to time in order to perform a DATEDIFF() calculation with another legitimate time field. My end goal is to create a report in SSRS.
The only way I have been able to perform this task in SSMS is by using:
,CAST(msdb.dbo.agent_datetime('19000101', P.[3]+'00') AS TIME(0)) AS [Reached Time]
P.[3] being a string field (Example value of 0744). I added the +'00' for milliseconds due to the format of "msdb.dbo.agent_datetime".
The above works perfectly in SSMS and gives a value of 07:44:00. However, this "msdb.dbo.agent_datetime" function will NOT work in SSRS. My report will only run if I remove any mention of "msdb.dbo.agent_datetime".
I need a different method to change this string value, such as 0744, to a legitimate time value of 07:44 or 07:44:00.
I have tried:
FORMAT(CONVERT(INT,P.[3]), 'HH:mm', 'en-us') --Returns value of HH:mm
CONVERT(VARCHAR, P.[3], 24) --Returns value of 0744
CONVERT(TIME, P.[3]) --Returns value of 00:00:00.0000000
CAST(P.[3] AS TIME) --Returns value of 00:00:00.0000000
CAST(CONVERT(INT,P.[3]) AS TIME) --Explicit conversion from data type int to time is not allowed.
Other combinations also error out. I have even tried to format the time in SSRS with no success.
I can make it look like a time by modifying the string, but then can't perform a calculation with DATEDIFF()
Please Help!
I can't see any reason why you cannot use the function in your dataset query assuming permissions are correct for the credentials set against the datasource.
Anyway, to cheat you could recreate the function in you own database and use that version.
If you run the following in SSMS
USE msdb
exec sp_helptext 'dbo.agent_datetime'
You will get the script as follows,
CREATE FUNCTION agent_datetime(#date int, #time int)
RETURNS DATETIME
AS
BEGIN
RETURN
(
CONVERT(DATETIME,
CONVERT(NVARCHAR(4),#date / 10000) + N'-' +
CONVERT(NVARCHAR(2),(#date % 10000)/100) + N'-' +
CONVERT(NVARCHAR(2),#date % 100) + N' ' +
CONVERT(NVARCHAR(2),#time / 10000) + N':' +
CONVERT(NVARCHAR(2),(#time % 10000)/100) + N':' +
CONVERT(NVARCHAR(2),#time % 100),
120)
)
END
Use this to create the same function in your database.
Of course now, you see how simple the function is, you could create one that does the entire conversion in a single step.
This works for me on SSMS:
declare #sourcetime char(4) = '1714'
select cast(left(#sourcetime, 2) + ':' + right(#sourcetime, 2) as datetime)

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.

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

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)

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!

SQL Server datetime in 12AM/PM format without the millisecond

I would like to return my datetime data to the following format:
mm/dd/yy hh:mi:ssAM
According to the CONVERT documentation the closest thing that matches my spec is '131'
SELECT CONVERT(varchar, GETDATE(), 131)
but it doesn't exactly match my specifications.
EDIT:
I ended up doing the date formatting in my application layer which is PHP.
It was as simple as using the strtotime function to generate a UNIX timestamp and pass it into date funciton.
$date = date('m/d/Y g:ia', strtotime($row['date_time']));
Try this:
SELECT CONVERT(varchar, GETDATE(), 101) +
REPLACE(CONVERT(varchar, GETDATE(), 0),REPLACE(CONVERT(varchar, GETDATE(),107), ',',''),'')
This basically uses a method that's what you want for the DATE, then adds it to the time portion of what you want for the time only.
Although I feel that formatting should really be part of the UI, I guess if you really need it the below works - I'm sure there is an easier way to do this - but make this a UDF, and just use it in whatever query you want.
declare #date varchar(50)
set #date = (select CONVERT(varchar, GETDATE(), 131))
set #date = (select LEFT(#date,len(#date) - 6) + ' ' + RIGHT(#date,2))
set #date = right(#date,LEN(#date) - 11)
select CONVERT(varchar, GETDATE(), 101) + #date
You can assemble it from DATEPART()'s, and create a user defined function from it for easy re-use.
This is untested off the top of my head.. give it a shot:
CREATE FUNCTION fnSpecDate()
RETURNS VARCHAR(24)
AS
BEGIN
DECLARE #outData VARCHAR(24)
set #outData =
CONVERT(varchar,DATEPART(mm,GETDATE())) + "/"
+ CONVERT(varchar,DATEPART(dd,GETDATE())) + "/"
+ CONVERT(varchar,DATEPART(yy,GETDATE())) + " "
+ CASE WHEN DATEPART(hh,GETDATE()) > 12
THEN CONVERT(varchar,DATEPART(hh,GETDATE()) - 12)
WHEN DATEPART(hh,GETDATE()) = 0
THEN '12'
ELSE CONVERT(varchar,DATEPART(hh,GETDATE()))
END + ":"
+ CONVERT(varchar,DATEPART(mm,GETDATE())) + ":"
+ CONVERT(varchar,DATEPART(ss,GETDATE()))
+ CASE WHEN DATEPART(hh,GETDATE()) > 11
THEN "PM"
ELSE "AM"
END
RETURN #outData
END
Then in any regular query, you can just include dbo.fnSpecDate() as myDate

Resources