Skip to content
Advertisement

How to get how many hour 4AM have there been between two dates in TSQL

I need to get how many of a specific hour have occurred between two dates in TSQL. Some examples:

The following would give the result = 1

declare @date1 datetime = '2019-10-01 00:00:00.000';
declare @date2 datetime = '2019-10-02 00:00:00.000';

The following would give the result = 0, as there has been 0 4AMs in between

declare @date1 datetime = '2019-10-01 05:00:00.000';
declare @date2 datetime = '2019-10-02 00:00:00.000';

The following would give the result = 2, as there has been 2 4AMs in between

declare @date1 datetime = '2019-10-01 03:00:00.000';
declare @date2 datetime = '2019-10-02 05:00:00.000';

The following would give the result = 2, as there has been 2 4AMs even though they are just on the 4:00AM time

declare @date1 datetime = '2019-10-01 04:00:00.000';
declare @date2 datetime = '2019-10-02 04:00:00.000';

I have tried something like this… but it is giving an incorrect answer

DECLARE @startdate AS DATETIME = '2019-10-01 03:00:00.000'
DECLARE @enddate   AS DATETIME = '2019-10-02 00:00:00.000'
DECLARE @hour int = 4

SELECT DATEDIFF(HOUR, @startdate, @endDate) / 24
     + 1 
     + CASE WHEN DATEPART(HOUR, @startdate) <= @hour AND 
                 DATEPART(HOUR, @endDate) >= @hour
            THEN 0
            ELSE -1
       END

Anyone who can shed some light I would appreciate it

Advertisement

Answer

The easiest way would be to remove 4 hours from both values, and then get the difference in days:

DECLARE @date1 datetime = '2019-10-01 00:00:00.000';
DECLARE @date2 datetime = '2019-10-02 00:00:00.000';

SELECT DATEDIFF(DAY,DATEADD(HOUR, -4, @date1),DATEADD(HOUR, -4, @date2)); --RETURNS 31, as there are 31 days bewteen 10 Jan and 10 Feb
GO

DECLARE @date1 datetime = '2019-10-01T04:30:00.000';
DECLARE @date2 datetime = '2019-10-02T03:59:00.000';

SELECT DATEDIFF(DAY,DATEADD(HOUR, -4, @date1),DATEADD(HOUR, -4, @date2)); --RETURNS 0, as 04:00 never got to

GO

DECLARE @date1 datetime = '2019-10-01T03:30:00.000';
DECLARE @date2 datetime = '2019-10-03T04:30:00.000';

SELECT DATEDIFF(DAY,DATEADD(HOUR, -4, @date1),DATEADD(HOUR, -4, @date2)); --RETURNS 3, as 04:00 occurs on 01, 02 and 03 of October

Seems the OP wants to count the event of 04:00 as well. I therefore remove a further second from the start time:

DECLARE @date1 datetime = '2019-10-01T04:00:00.000';
DECLARE @date2 datetime = '2019-10-02T04:00:00.000';

SELECT DATEDIFF(DAY,DATEADD(SECOND,-1,DATEADD(HOUR, -4, @date1)),DATEADD(HOUR, -4, @date2)); --returns 2

DECLARE @date1 datetime = '2019-10-01T04:00:00.000';
DECLARE @date2 datetime = '2019-10-01T04:00:01.000';

SELECT DATEDIFF(DAY,DATEADD(SECOND,-1,DATEADD(HOUR, -4, @date1)),DATEADD(HOUR, -4, @date2)); --Returns 1

If you’re actually storing values accurate to 1/300 of a second, then don’t use 1 second, use 3 millseconds, to ensure utmost accuracy.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement