Remove minutes and seconds and then convert to UTC timezone - sql

I have column with time stamp data like this
2021-12-09 08:01:00.520
I want to remove the minutes and second and then convert the date to UTC timezone in one line.
I tried this code
SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, 0, Time_Stamp), 0) From Table1
I get this result
2021-12-09 08:00:00.000
and I tried this code
SELECT DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), GETDATE()), Time_Stamp)From Table1
I get this result
2021-12-09 16:01:00.520
What I expected is
2021-12-09 16:00:00.000
How to combine the select statement into one line in simple way

Here is another way.
To remove the minute, seconds and only keep the hour, you may use the following query
DATEADD(HOUR, DATEDIFF(HOUR, 0, Time_Stamp), 0)
To convert to the UTCDate, just find the different in hour () between GETDATE() and GETUTCDATE() (Since you are not interested in the minute and seconds anyway) and add that to the above query
Putting all together
DATEADD(HOUR, DATEDIFF(HOUR, 0, Time_Stamp) + DATEDIFF(HOUR, GETDATE(), GETUTCDATE()), 0)

Convert the date to a string and truncate to remove the minutes and seconds. Then add the difference in minutes between your timezone and UTC.
select dateadd(minute,datediff(minute,getdate(),getutcdate()),convert(datetime2(0),convert(varchar(13),getdate(),126)+':00:00',126));

SELECT DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), GETDATE()), dateadd(hour, datediff(hour, 0, Time_Stamp), 0)) FROM Table1

Related

SQL, get any data between two days and specific time

I am trying to get any data that is between that time range of two days ago until yesterday.
Example: Retrieve any data between 3 PM two days ago and yesterday 3 PM. This query should work on the daily basis.
I am thinking something like but just don't know where to insert the time
select * from dbo.table where system_date between getdate()-2 and getdate()-1
You can use CAST(CAST(GETDATE() AS date) AS datetime) to get the beginning of today's date, then use DATEADD to subtract 1 or 2 days, and add 15 hours.
I strongly suggest you use >= AND < on dates, rather than BETWEEN, otherwise you get "on the interval" issues.
SELECT t.*
FROM dbo.[table] t
WHERE t.system_date >= DATEADD(hour, 15, DATEADD(day, -2, CAST(CAST(GETDATE() AS date) AS datetime)))
AND t.system_date < DATEADD(hour, 15, DATEADD(day, -1, CAST(CAST(GETDATE() AS date) AS datetime)));
try this
select *
from dbo.table
where system_date between dateadd(day, datediff(day, 2, getdate()), '15:00:00') and dateadd(day, datediff(day, 1, getdate()), '15:00:00')
You should use DATEADD for subtracting dates. Your query will look like this.
select *
from table
where system_date between dateadd(day, -2, getdate()) and dateadd(day, -1, getdate())

Truncate timestamp

I would like into a stored procedure, truncate timestamp input values at the top hour or at the lower hour.
For example, if my input values are 2020-02-12 06:56:00 and 2020-02-12 07:14:00, I would like to transforme it in 2020-02-12 06:00:00 and 2020-02-12 08:00:00
Is a cast function can work?
You can construct the new datetimes from the parts that you want of your original datetimes.
declare #start datetime = '2020-02-12 06:56:00'
declare #end datetime = '2020-02-12 07:14:00'
select #start as OriginalStart,
#end as OriginalEnd,
datetimefromparts(year(#start), month(#start), day(#start), datepart(hour, #start), 0, 0, 0) as TruncatedStart,
dateadd(hour, 1, datetimefromparts(year(#end), month(#end), day(#end), datepart(hour, #end), 0, 0, 0)) as TruncatedEnd
The first truncation of the interval is the lower hour, and the second one adds an additional hour so it returns the higher hour.
PS: If what you want is to round to the nearest hour, then you can add 30 minutes and truncate :
declare #date datetime = '2020-02-12 06:56:00'
set #date = dateadd(minute, 30, #date)
select datetimefromparts(year(#date), month(#date), day(#date), datepart(hour, #date), 0, 0, 0) as NearestHour
or in a single step (using Lepetit's shortcut for truncation) :
declare #date datetime = '2020-02-12 06:56:00'
select dateadd(hour, datediff(hour, 0, dateadd(minute, 30, #date)), 0) AS NearestHour
This is a simpler solution:
declare #start datetime = '2020-02-12 06:56:00'
declare #end datetime = '2020-02-12 07:14:00'
select #start as OriginalStart,
#end as OriginalEnd,
dateadd(hour, datediff(hour, 0, #start), 0) as TruncatedStart,
dateadd(hour, datediff(hour, 0, dateadd(hour, 1, #end)), 0) as TruncatedEnd
In both cases the function substracts the hour part from the original timestamp. For the TruncatedEnd, one hour is added, so that the result is the subsequent hour.
Using a bit of arithmetic calculation, convert to hours with decimal and use floor() and ceiling() to perform the round up / down
first it find the time different with 00:00:00 in terms of second. convert(date, date_col) convert the datetime to date, so effectively it is 00:00:00
datediff(second, convert(date, date_col), date_col)
then you divide by 60 x 60 = 3600 seconds. Gives you fraction of hours
then you use floor() or ceiling() to perform the rounding
and lastly you add that back to the date (convert(date, date_col))
Final query
select *,
RoundDown = convert(datetime, convert(date, date_col))
+ dateadd(hour, floor(datediff(second, convert(date, date_col), date_col) / (3600.0)), 0),
RoundUp = convert(datetime, convert(date, date_col))
+ dateadd(hour, ceiling(datediff(second, convert(date, date_col), date_col) / (3600.0)), 0)
from (
values
('2020-02-12 06:56:00'),
('2020-02-12 07:14:00')
) d (date_col)
/*
2020-02-12 06:56:00 2020-02-12 06:00:00 2020-02-12 07:00:00
2020-02-12 07:14:00 2020-02-12 07:00:00 2020-02-12 08:00:00
*/
EDIT : a much simpler query below
find the different in minute divide by 60.0 minutes to get different in terms of hour (with decimal places) and then apply floor or ceiling. Finally add that result back
select getdate() as Now,
dateadd(hour, floor(datediff(minute, 0, getdate()) / 60.0), 0) as RoundDown,
dateadd(hour, ceiling(datediff(minute, 0, getdate()) / 60.0), 0) as RoundUp

SQL statement to select all rows from previous day with time

Need to select rows from the previous day but before 08:00 am.
(date >= dateadd(day,datediff(day,1,GETDATE()),0)
AND CONVERT(varchar, date,108) BETWEEN '00:00:00' AND '08:00:00')
return rows of from the previous day and before 08:00 am.
You can use:
where date >= dateadd(day, -1, convert(date, getdate())) and
date < dateadd(hour, -16, convert(date, getdate()))
This query is structured so it can make use of indexes.
You can also phrase this as:
where convert(date, [date]) = dateadd(day, -1, convert(date, getdate()) and
convert(time, [date]) <= '08:00:00'
This should also use indexes, because conversion to a date is perhaps the only function that does not prevent the use of an index.
You're on the right track. This does a BETWEEN check on the beginning of the day yesterday and the beginning of the day yesterday + 8 hours:
date BETWEEN dateadd(day,datediff(day,1,GETDATE()),0)
AND dateadd(hour, 8, dateadd(day,datediff(day,1,GETDATE()),0))

select only hours from date

The below query returns value in this format 2017-11-18 16:00:00.000
How can i return value in hours only
Desired format
16:00:00.000
17:00:00.000
18:00:00.000
Query
SELECT DATEADD(Hour, DATEDIFF(Hour, 0, GetDate()), 0)
You can convert the value to time:
SELECT CONVERT(TIME, DATEADD(Hour, DATEDIFF(Hour, 0, GetDate()), 0))
I would be more inclined to write the logic as:
SELECT dateadd(hour, datepart(hour, getdate()), cast('00:00' as time))
There really is no difference . . . just the logic of adding a certain number of hours to '00:00' seems simpler.

Getdate() functionality returns partial day in select query

I have a query -
SELECT * FROM TABLE WHERE Date >= DATEADD (day, -7, -getdate()) AND Date <= getdate();
This would return all records for each day except day 7. If I ran this query on a Sunday at 17:00 it would only produce results going back to Monday 17:00. How could I include results from Monday 08:00.
Try it like this:
SELECT *
FROM SomeWhere
WHERE [Date] > DATEADD(HOUR,8,DATEADD(DAY, -7, CAST(CAST(GETDATE() AS DATE) AS DATETIME))) --7 days back, 8 o'clock
AND [Date] <= GETDATE(); --now
That's because you are comparing date+time, not only date.
If you want to include all days, you can trunc the time-portion from getdate(): you can accomplish that with a conversion to date:
SELECT * FROM TABLE
WHERE Date >= DATEADD (day, -7, -convert(date, getdate())
AND Date <= convert(date, getdate());
If you want to start from 8 in the morning, the best is to add again 8 hours to getdate.
declare #t datetime = dateadd(HH, 8, convert(datetime, convert(date, getdate())))
SELECT * FROM TABLE
WHERE Date >= DATEADD (day, -7, -#t) AND Date <= #t;
NOTE: with the conversion convert(date, getdate()) you get a datatype date and you cannot add hours directly to it; you must re-convert it to datetime.
Sounds like you want to remove the time. Correct? If so then do the following.
SELECT * FROM TABLE WHERE Date >= (DATEADD (day, -7, -getdate()) AND Date DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0))