SQL date conversion HHMMSS.CCCNNNNNN to yyyy-mm-dd hh:mi:ss.mmm - sql

I have data in this format : 114643.052303537 (HHMMSS.CCCNNNNNN).
I need to convert it to this format : 2018-04-25 12:40:59.573 (yyyy-mm-dd hh:mi:ss.mmm), strip of the date part ( i.e. 2018-04-25 ) and calculate the time difference between two formats.
Could you please help with this?

I need the time difference in hh:mi:ss.mmm format
The way to get this is to convert BOTH values to milliseconds (looking at only the time portion for the value that has a date); calculate the difference with simple subtraction, and then convert the result to hh:mi:ss.mmm with division and modulo operations.

declare #dt datetime = '2018-04-25 12:40:59.573'
declare #dunno varchar(16) = '114643.052303537'
Strip the date off the datetime and give it today's date
getdate() + right(convert(varchar,#dt,113),12)
Convert the varchar to time and give it today's date
getdate() + left(stuff(stuff(#dunno,3,0,':'),6,0,':'),8)
Find the milliseconds between them
datediff(millisecond,getdate() + left(stuff(stuff(#dunno,3,0,':'),6,0,':'),8),getdate() + right(convert(varchar,#dt,113),12))
Put it all together in your format
select
convert(char(13),
dateadd(millisecond,
datediff(millisecond,getdate() + left(stuff(stuff(#dunno,3,0,':'),6,0,':'),8),getdate() + right(convert(varchar,#dt,113),12)),
'01/01/00'),
14)
Depending on the speed of your server and other code, it'd be wise to use a variable for GETDATE() at the beginning to prevent millisecond, or even second differences during conversion.
declare #dt datetime = '2018-04-25 12:40:59.573'
declare #dunno varchar(16) = '114643.052303537'
declare #today datetime = getdate()
declare #dunno2 datetime
declare #dt2 datetime
set #dt2 = #today + right(convert(varchar,#dt,113),12)
set #dunno2 = #today + left(stuff(stuff(#dunno,3,0,':'),6,0,':'),8)
select
convert(char(13),
dateadd(millisecond,
datediff(millisecond,#dunno2,#dt2),
'01/01/00'),
14)

Related

SQL Convert data time format (yyyy-mm-dd 00:00:00.000) to yyyymmdd as int

It must be very simple, but I don't know SQL language very well.
I need to filter data by date which is in this format:
How to do it right to filter data this way?
FROM [TableName] where
FileDate>=20220505
I've already tried the command LEFT and CAST but with no success
Something like this may work:
declare #now Datetime = getdate();
declare #intNow int = cast(cast(datepart(year, #now) as varchar(4)) + RIGHT('00'+CAST(datepart(month, #now) AS VARCHAR(2)),2) + RIGHT('00'+CAST(datepart(day, #now) AS VARCHAR(2)),2) as int)
Although if you have your date to check against in the right format e.g. using:
declare #dateToCheck Datetime = cast(cast(20220505 as varchar) as datetime)
And then
FileDate>= #dateToCheck
it should work
You can create an integer representation of your datetime by multiplying and adding the date parts:
year * 10000 20220000
month * 100 500
day 5
-------------------------
20220505
...
FROM [TableName]
WHERE (DATEPART(year, [FileDate]) * 10000) + (DATEPART(month, [FileDate]) * 100) + (DATEPART(day, [FileDate])) >= 20220505
However I'd still look into fixing the condition input format instead.
Credit to #Rangani in Yesterday's date in SSIS package setting in variable through expression for "multiply and add instead of string concat" trick

String to Date in SQL

Is there a way to quickly convert this date format to DATE in SQL?
{ “date_from”:”22112017”,”date_to”:”22112017”}
This is needed to filter the data between these dates
(There are a lot of conversion entries on the web, but I haven't found that format)
EDIT:
DECLARE #EndDate DATE = CONVERT(VARCHAR, '22112017', 103)
PRINT #EndDate
Error: Conversion failed when converting date and/or time from character string.
WHAT I HAVE:
#StartDate = '22112017'
#EndDate = '22112020'
WHAT I NEED TO DO:
SELECT * from tblMy WHERE ReceivedDate BETWEEN #StartDate AND #EndDate
If you fix your JSON to not use stylised double quotes (”) and use standard ones (") then you can parse this as JSON. Once you extract the values, you can inject a couple of / characters in and then convert to a date with the style code 103 (dd/MM/yyyy):
DECLARE #String nvarchar(MAX) = N'{ "date_from":"22112017","date_to":"22112017"}';
SELECT CONVERT(date,STUFF(STUFF(OJ.date_from,5,0,'/'),3,0,'/'),103) AS date_from,
CONVERT(date,STUFF(STUFF(OJ.date_to,5,0,'/'),3,0,'/'),103) AS date_to
FROM (VALUES(#String))V(S)
CROSS APPLY OPENJSON(V.S)
WITH (date_from varchar(8),
date_to varchar(8)) OJ;
Edit:
Seems the OP has moved their goal posts, this has nothing to do with JSON.
The problem here is your literal strings. When using literal strings for a date and time data type use either yyyyMMdd or yyyy-MM-ddThh:mm:ss.nnnnnnn as they are both unambiguous regardless of language and data type:
DECLARE #StartDate date,
#EndDate date;
SET #StartDate = '20171222';
SET #EndDAte = '20201122';
SELECT *
FROM tblMy
WHERE ReceivedDate BETWEEN #StartDate AND #EndDate;
I would suggest converting the value to a standard SQL Server date value. This is pretty simple:
select convert(date, left(val, 4) + substring(val, 3, 2) + right(val, 2))
The standard date format is YYYYMMDD. Yours is DDMMYYYY, so string operations can convert it to the correct format. Of course, what you should probably do is to convert the value to a date in the application layer and pass the date value in as a parameter.
This should fix the error "Error: Conversion failed when converting date and/or time from character string."
DECLARE #EndDate VARCHAR(MAX) = '22112017'
DECLARE #datevar date = CAST(SUBSTRING(#EndDate, 3, 2) + '/' + SUBSTRING(#EndDate,
1, 2) + '/' + SUBSTRING(#EndDate, 5, 4) AS date);
SELECT #datevar;

Convert LOCAL TIME data type value to UTC time

I am trying to write a query that returns records that fall between two dates (each with a cutoff in TIME format). So far I have the following:
For example:
SELECT
T.CustomerName,
T.MoneyToTransfer
FROM dbo.[Transfer] T
WHERE T.CreatedDate BETWEEN '2016-05-10 03:00:00.0000000' AND '2016-05-11 03:00:00.0000000'
However the cutoff time 03:00:00.0000000 is only a placeholder for how I think the query needs to be formatted - the TIME needs to be retrieved from another table 'TransferSubscriber' from field 'Cutoff' stored as data type TIME. The problem is that this Cutoff field in table TransferSubscriber is stored in LOCAL time (in a TIME data type). I need to convert this TIME to UTC, and place it in my BETWEEN statement in the TIME part of the comparison (where the 03:00:00.0000000).
I have written the following, which has issues concatenating the date and time variables into one:
DECLARE #startDate DATE = (SELECT CONVERT(VARCHAR, '2016-07-13', 110))
DECLARE #Cutoff AS TIME(7) = (SELECT TOP 1 S.CutoffTime FROM Subscriber.dbo.TransferSubscriber S WHERE ID = 10)
DECLARE #CutoffUTC TIME = (SELECT DATEADD(second,DATEDIFF(second, GETDATE(), GETUTCDATE()), #Cutoff))
DECLARE #StartDateFinal = #startDate + #CutoffUTC
#StartDateFinal throws error:
"Operand data type date is invalid for add operator."
I am sure there is a better way to convert local TIME to UTC time, and use it to compare two DATETIME fields.
Any help would be great!
Try the following,
DECLARE #startDate DATE = (SELECT CONVERT(VARCHAR, '2016-07-13', 110))
DECLARE #Cutoff AS TIME(7) = (SELECT TOP 1 S.CutoffTime FROM Subscriber.dbo.TransferSubscriber S WHERE ID = 10)
DECLARE #CutoffUTC TIME = (SELECT DATEADD(second,DATEDIFF(second, GETDATE(), GETUTCDATE()), #Cutoff))
DECLARE #StartDateFinal DATETIME2
SELECT #StartDateFinal=CAST(CAST(#startDate AS VARCHAR) +' '+ CAST(#CutoffUTC AS VARCHAR) AS DATETIME2)
SELECT #StartDateFinal
Hope it helps.

Get DAY from Date

I need select day from #ReportDay
DECLARE #ReportDay DATETIME = '2017-10-02 12:00:03.140'
DECLARE #currentReportDay DATETIME = DATEPART(day, #ReportDay )
But in result I've '1900-01-03 00:00:00.000'. How it can be fix?
DECLARE #ReportDay DATETIME = FORMAT(Now(),'YYYY-MM-DD')
DECLARE #currentReportDay DATETIME = DATEPART(day, #ReportDay)
This would give you today's date in YYYY-MM-DD format
DATEPART gives you back an integer
DECLARE #ReportDay DATETIME = '2017-10-02 12:00:03.140'
DECLARE #currentReportDay INT = DATEPART(day, #ReportDay )
Others have already raised the ambiguity of your question but to add some explanation and hopefully clear up some confusion.
The reason why you are getting '1900-01-03 00:00:00.000'
is because DATEPART(day, #ReportDay) will return an integer for the day of the month, in your case 2. When converted to a DATETIME 2 is actually the 3rd date. 0 is 1/1/1900, 1 is 1/2/1900. and so forth.
So if you want the DATE itself you can use CONVERT or CAST. Some other string manipulation techniques exist and FORMAT() is one of them but they are not worth looking at as will have much poorer performance and take additional CASTS and CONVERTS anyway. What you want to do is to DROP the TIME off the DATETIME. Best way of doing that is to CAST it to a DATE which has no TIME component.
DECLARE #currentReportDay DATETIME = CAST(CAST(#ReportDay AS DATE) AS DATETIME)
Note because the second CAST back to DATETIME isn't really necessary in this code as it will inherently happen so you could shorten to:
DECLARE #currentReportDay DATETIME = CAST(#ReportDay AS DATE)
And to round this out. If you actually want the DAY of the Month then simply change from DATETIME data type to INT.
DECLARE #currentReportDay INT = DATEPART(day, #ReportDay )

Transforming nvarchar day duration setting into datetime

I have a SQL Server function which converts a nvarchar day duration setting into a datetime value.
The day duration format is >days<.>hours<:>minutes<, for instance 1.2:00 for one day and two hours.
The format of the day duration setting can not be changed, and we can be sure that all data is correctly formatted and present.
Giving the function a start time and the day duration setting it should return the end time.
For instance: 2010-01-02 13:30 ==> 2010-01-03 2:00
I'm using a combination of charindex, substring and convert methods to calculate the value,
which is kind of slow and akward. Is there any other way to directly convert this day duration setting into a datetime value?
Not from what I can see. I would end up with a similar bit of SQL like you, using charindex etc. Unfortunately it's down to the format the day duration is stored in. I know you can't change it, but if it was in a different format then it would be a lot easier - the way I'd usually do this for example, is to rationalise the duration down to a base unit like minutes.
Instead of storing 1.2:00 for 1 day and 2 hours, it would be (1 * 24 * 60) + (2 * 60) = 1560. This could then be used in a straightforward DATEADD on the original date (date part only).
With the format you have, all approaches I can think of involve using CHARINDEX etc.
One alternative would be to build a string with the calculation. Then you can run the generated SQL with sp_executesql, specifying #enddate as an output parameter:
declare #startdate datetime
declare #duration varchar(10)
declare #enddate datetime
set #startdate = '2010-01-02 13:30'
set #duration = '0.12:30'
declare #sql nvarchar(max)
set #sql = 'set #enddate = dateadd(mi,24*60*' +
replace(replace(#duration,'.','+60*'),':','+') + ', #startdate)'
exec sp_executesql #sql,
N'#startdate datetime, #enddate datetime out',
#startdate, #enddate out
This creates a string containing set #enddate = dateadd(mi,24*60*0+60*12+30, #startdate) and then runs it.
I doubt this is faster than the regular charindex way:
declare #pos_dot int
declare #day int
declare #hour int
declare #minute int
select
#pos_dot = charindex('.',#duration),
#day = cast(left(#duration, #pos_dot-1) as int),
#hour = cast(left(right(#duration, 5), 2) as int),
#minute = cast(right(#duration, 2) as int),
#enddate = dateadd(mi, 24*60*#day + 60*#hour + #minute, #startdate)