Convert varchar string to datetime - sql-server

I am having an issue converting below to a DateTime, I am only able to get the date portion of the string. My goal is to get both the date & time.
declare #col varchar(14) = '20220602235900';
select CONVERT(datetime, CAST(#col AS varchar(8)), 121) dtimecre

Steps:
Read the documentation for CONVERT and pick the closest format to use
Do some string manipulation to get the desired format
Convert.
DECLARE #col varchar(14) = '20220602235900';
SELECT
CONVERT(date, SUBSTRING(#col,1,8), 121) [Date Component]
, CONVERT(time, SUBSTRING(#col,9,2) + ':' + SUBSTRING(#col,11,2) + ':' + SUBSTRING(#col,13,2), 8) [Time Component]
, CONVERT(datetime, SUBSTRING(#col,1,4) + '-' + SUBSTRING(#col,5,2) + '-' + SUBSTRING(#col,7,2) + ' ' + SUBSTRING(#col,9,2) + ':' + SUBSTRING(#col,11,2) + ':' + SUBSTRING(#col,13,2), 120) [DateTime Representation];
Returns:
Date Component
Time Component
DateTime Representation
2022-06-02
23:59:00.0000000
2022-06-02 23:59:00.000

And another variant with a smaller amount of SUBSTRING:
DECLARE #col varchar(14) = '20220602235900';
SELECT DateComponent = CAST(DatePartString AS DATE),
TimeComponent = CAST(TimePartString AS TIME),
DateAndTime = CAST(DatePartString + ' ' + TimePartString AS DATETIME)
FROM (VALUES(#col)) AS O (DateColumn)
CROSS APPLY (
SELECT DatePartString = LEFT(DateColumn, 8),
TimePartString = FORMAT(CAST(SUBSTRING(DateColumn, 9, 6) AS INT), '##:##:##')
) AS String;

Related

Datetime is NULL when time format differs

I have specific time scenario which can be 4 digit, 6 digit or can be NULL or string as mentioned below. Here in scenario 3 & 4 my method of calculating datetime is not working and coming as NULL
Is there any way to get date with 00:00:00:000 as time for case 3 & 4?
& for 1 it should be 10:02:00:000
DECLARE #DATE VARCHAR(10) =CAST(GETDATE() AS DATE)
DECLARE #Time1 VARCHAR(10) = '1002'
DECLARE #Time2 VARCHAR(10) = '160634'
DECLARE #Time3 VARCHAR(10) = '0900XX'
DECLARE #Time4 VARCHAR(10) = ''
SELECT TRY_CONVERT(DATETIME, #DATE +' '
+LEFT(ltrim(#Time1), 2)
+ ':' + SUBSTRING(#Time1, 3, 2)
+ ':' + RIGHT(rtrim(#Time1), 2)) , TRY_CONVERT(TIME, #Time1), #Time1 AS Time
SELECT TRY_CONVERT(DATETIME, #DATE +' '
+LEFT(ltrim(#Time2), 2)
+ ':' + SUBSTRING(#Time2, 3, 2)
+ ':' + RIGHT(rtrim(#Time2), 2)) , TRY_CONVERT(TIME, #Time2), #Time2 AS Time
SELECT TRY_CONVERT(DATETIME, #DATE +' '
+LEFT(ltrim(#Time3), 2)
+ ':' + SUBSTRING(#Time3, 3, 2)
+ ':' + RIGHT(rtrim(#Time3), 2)) , TRY_CONVERT(TIME, #Time3), #Time3 AS Time
SELECT TRY_CONVERT(DATETIME, #DATE +' '
+LEFT(ltrim(#Time4), 2)
+ ':' + SUBSTRING(#Time4, 3, 2)
+ ':' + RIGHT(rtrim(#Time4), 2)) , TRY_CONVERT(TIME, #Time4), #Time4 AS Time
I would, personally, "pad out" the values to be 6 digits, inject the : characters, and then use TRY_CONVERT. Then you use ISNULL to return midmight for failed converions:
SELECT ISNULL(TRY_CONVERT(time(0),STUFF(STUFF(RIGHT('000000' + V.VarcharTime,6),5,0,':'),3,0,':')),'00:00:00')
FROM (VALUES(#Time1),
(#Time2),
(#Time3),
(#Time4))V(VarcharTime);
If 1002 is meant to be 10:02:00 rather than 00:10:02 then pad on the right, rather than the left:
SELECT ISNULL(TRY_CONVERT(time(0),STUFF(STUFF(LEFT(V.VarcharTime+'000000',6),5,0,':'),3,0,':')),'00:00:00')
FROM (VALUES(#Time1),
(#Time2),
(#Time3),
(#Time4))V(VarcharTime);
..................
DECLARE #Time4 VARCHAR(10) = ''
select #Time1 = concat(cast(#Time1 as varchar(8)), replicate('0', 8));
select #Time2 = concat(cast(#Time2 as varchar(8)), replicate('0', 8));
select #Time3 = concat(cast(#Time3 as varchar(8)), replicate('0', 8));
select #Time4 = concat(cast(#Time4 as varchar(8)), replicate('0', 8));
SELECT TRY_CONVERT(DATETIME, #DATE +' '......................

SQL server date time

I am trying to get object which its start date + start time have passed or equal to current datetime and its end date + end time hasn't pass the current datetime. I tried convert current datetime to nvarchar as all my columns are nvarchar. I also tried converting my columns to datetime type but it doesn't work too. Please help
Column:
startDate - nvarchar (dd/mm/yyyy)
startTime - nvarchar (hh:mm) 24 hr
endDate - nvarchar(dd/mm/yyyy)
endTime - nvarchar(hh:mm) 24hr
i did try to but datetime betwween startDate + startTime AND endDate +startTime,
but it doesn't seems to work :
SELECT * FROM Promo
WHERE membership = '1'
AND promoStatus = '1'
AND CONVERT(NVARCHAR, GetDate(), 101) + ' ' +
CONVERT(NVARCHAR, DATEPART(hh, GetDate())) + ':' +
RIGHT('0' + CONVERT(NVARCHAR, DATEPART(mi, GetDate())), 2) BETWEEN
startDate + ' ' + startTime
AND endDate + ' ' + endTime
i did try other method too :
SELECT * FROM Promo
WHERE membership = '1'
AND promoStatus = '1'
AND startDate + ' ' + startTime <= CONVERT(NVARCHAR, GetDate(), 101) + ' ' +
CONVERT(NVARCHAR, DATEPART(hh, GetDate())) + ':' +
RIGHT('0' + CONVERT(NVARCHAR, DATEPART(mi, GetDate())), 2)
AND endDate + ' ' + endTime >= CONVERT(NVARCHAR, GetDate(), 101) + ' ' +
CONVERT(NVARCHAR, DATEPART(hh, GetDate())) + ':' +
RIGHT('0' + CONVERT(NVARCHAR, DATEPART(mi, GetDate())), 2)
You could do it like this:
SELECT *
FROM Promo
WHERE
membership = '1'
AND promoStatus = '1'
AND CAST(CONVERT(VARCHAR(16), GETDATE(), 120) AS DATETIME) BETWEEN
CONVERT(DATETIME, #startDate, 103) + CONVERT(DATETIME, #startTime)
AND CONVERT(DATETIME, #endDate, 103) + CONVERT(DATETIME, #endTime)
This line:
CAST(CONVERT(VARCHAR(16), GETDATE(), 120) AS DATETIME)
gets the current date time up to its minutes, meaning this will strip off the seconds and milliseconds part of the GETDATE().
And this line:
CONVERT(DATETIME, #startDate, 103) + CONVERT(DATETIME, #startTime)
will combine your date and time variables to form a new DATETIME value.
Note that you could have done away with with this if you design the tables using the proper data types.
Try this
SELECT * FROM Promo
WHERE membership = '1'
AND promoStatus = '1'
AND CAST(CONVERT(VARCHAR(16), GetDate(), 120) AS DATETIME)
BETWEEN CONVERT(DATETIME, startDate + ' ' + startTime, 120)
AND CONVERT(DATETIME, endDate + ' ' + endTime, 120)

storing current date time with milisec in varchar column - mssql

storing current date time with milisec in varchar column - mssql
i do have a varchar max column
i want to store current date with mili seconds in a column
with Concatenating the day-month-year-h-m-s-ms
Like
2304201310151515
Try this :-
SELECT REPLACE(CONVERT(varchar(max), getdate(), 103), '/', '')+
REPLACE(CONVERT(varchar(max), getdate(), 114), ':', '')
Try this one -
DECLARE #date DATETIME
SELECT #date = GETDATE()
SELECT
REPLACE(CONVERT(VARCHAR(20), #date, 104), '.', '') +
LEFT(REPLACE(CONVERT(VARCHAR(20), #date, 114), ':', ''), 8)
DECLARE #text VARCHAR(20)
SELECT #text = '2304201310151515'
SELECT
CAST(
SUBSTRING(#text, 5, 4) +
SUBSTRING(#text, 3, 2) +
SUBSTRING(#text, 1, 2) AS DATETIME)
+
CAST(
SUBSTRING(#text, 9, 2) + ':' +
SUBSTRING(#text, 11, 2) + ':' +
SUBSTRING(#text, 13, 2) + '.' +
SUBSTRING(#text, 15, 2) AS TIME)
I don't know what you use the varchar column for, but I highly recommend you use the yyyymmddhhmmssmmm format as it is sortable.
declare #date datetime = '20130423 10:15:15.15' -- Works in SQL 2008
select replace(replace(replace(replace(convert(varchar /* defaults to 30 char*/, #date, 121)
, '-', '')
, ':', '')
, '.', '')
, ' ', '')
Also, if you really want 2 digit milliseconds, then limit the characters returned from the convert function to varchar(22).
declare #date datetime = '20130423 10:15:15.15' -- Works in SQL 2008
select replace(replace(replace(replace(convert(varchar(22), #date, 121)
, '-', '')
, ':', '')
, '.', '')
, ' ', '')

CAST varchar to datetime in dynamic SQL

I keep getting the following error:
Msg 241, Level 16, State 1, Line 9 Conversion failed when converting
datetime from character string.
Here is the code I am trying to execute:
DECLARE #v_sql varchar(max),
#v_database varchar(25),
#vStartTime DATETIME,
#vEndTime DATETIME
SELECT #v_database = N'[DATABASE_NAME]', #vStartTime = '2012-09-27', #vEndTime = '2012-11-27'
SELECT #v_sql = N'SELECT
(SELECT ID FROM DATASTORE.DBO.PLANT WHERE DESCRIPTION = ''Henderson''),
SEQ,
AID,
NAME,
GRP,
AREA,
PRIO,
CASE ITIME WHEN ''-'' THEN NULL ELSE CAST(SUBSTRING(ITIME,1,8) + '' '' + SUBSTRING(ITIME,9,2) + '':'' + SUBSTRING(ITIME,11,2) + '':'' + SUBSTRING(ITIME,13,2) AS DATETIME) END ITIME,
CASE ATIME WHEN ''-'' THEN NULL ELSE CAST(SUBSTRING(ATIME,1,8) + '' '' + SUBSTRING(ATIME,9,2) + '':'' + SUBSTRING(ATIME,11,2) + '':'' + SUBSTRING(ATIME,13,2) AS DATETIME) END ATIME,
CASE NTIME WHEN ''-'' THEN NULL ELSE CAST(SUBSTRING(NTIME,1,8) + '' '' + SUBSTRING(NTIME,9,2) + '':'' + SUBSTRING(NTIME,11,2) + '':'' + SUBSTRING(NTIME,13,2) AS DATETIME) END NTIME,
DUR,
MSG,
VAR1,
VAR2,
VAR3,
VAR4,
OPR,
USER_COMMENT
FROM ' + #v_database + '.PROD.ALARM
WHERE CAST(substring(ITIME, 1, 4) + ''-'' + substring(ITIME, 5, 2) + ''-'' + substring(ITIME, 7, 2) + '' '' + substring(ITIME,9,2) + '':'' + substring(ITIME,11,2) + '':'' + substring(ITIME,13,2) + substring(ITIME,15,3) AS DATETIME) BETWEEN ' + #vStartTime +' AND ' + #vEndTime + ' ORDER BY ITIME'
EXEC(#v_sql)
Any help would be much appreciated, I am looking into this for a co-worker and it's got us both stumped.
Edit with a bit more digging, we were able to resolve it ourselves, passing parameters to sp_executesql:
declare
#vSql NVARCHAR(MAX),
#vParam NVARCHAR(MAX),
#vDatabase VARCHAR(15)
SET #vParam = '#vStartTime DATETIME, #vEndTime DATETIME'
SELECT #vSql = '
SELECT ''
'+ #vDatabase + ''',
ITEM_CODE,
SOURCE,
DEST,
TRAN_DT,
MILL_NAME,
NULL
FROM ' + #vDatabase + '.PROD.GRD_LOG
WHERE TRAN_DT BETWEEN #vStartTime AND #vEndTime'
EXEC sp_executesql #vSql, #vParam, #vStartTime, #vEndTime
By making the variables NVARCHAR(MAX), and then using sp_executesql instead of just executing the #vSql variable, we were able to resolve our issue.
Thanks to anyone who might have been looking into this.
In your original dynamic SQL, you were trying to add datetime variable to a text string which results in SQL attempting to convert the text string to a datetime value (by the order of precedence of conversion). You need to set the variables to nvarchar as well to avoid conversion in the original dynamic SQL.

combine date and time column problem

Using SQL Server 2005
Date Time
20060701 090000
20060702 020000
20060703 180000
...
Date and Time datatype is varchar
Tried Query
select Convert(datetime, Convert(char(10), date, 103) + ' ' + Convert(char(8), time, 108), 103) from table
SELECT
CAST(
DATEADD(dd, 0, DATEDIFF(dd, 0, date)) + ' ' +
DATEADD(Day, -DATEDIFF(Day, 0, time), time)
as datetime) from table
It showing error as out of range value.
How to solve this issue.
Need Sql Query Help
First off, why are you storing a DATETIME in a VARCHAR?
This should be able to help
DECLARE #Table TABLE(
Val VARCHAR(20)
)
INSERT INTO #Table (Val) SELECT '20060701 090102'
INSERT INTO #Table (Val) SELECT '20060702 020000'
INSERT INTO #Table (Val) SELECT '20060703 180000'
SELECT *,
CAST(SUBSTRING(Val,1,8) + ' ' + SUBSTRING(Val,10,2) + ':' + SUBSTRING(Val,12,2) + ':' + SUBSTRING(Val,14,2) AS DATETIME)
FROM #Table
I came across a similar issue a few years ago, when importing HL7 messages. Here is a copy of the function I used. It creates a DateTime string with the time component correctly separated into hh:mm:ss, which is needed for the cast to DateTime.
CREATE FUNCTION fn_StringDateTietoDateTime
(
#Date varchar(15)
)
RETURNS datetime
AS
BEGIN
DECLARE #Result DATETIME
SET #Result = NULL
If len(#Date) > 0
BEGIN
SELECT #Result = CAST(SUBSTRING(#hl7date, 1, 8) + ' ' + SUBSTRING(#hl7date, 10, 2) + ':' +
SUBSTRING(#date, 12, 2) + ':' + SUBSTRING(#date,14, 2) AS DATETIME)
END
RETURN #RESULT
END

Resources