This function, F_DATETIME_RANGE_MIDPOINT, computes the midpoint in time between two input parameter datetime values, @start and @end, and returns the midpoint as a datetime. The midpoint result is accurate to the nearest SQL Server clock tick of 1/300 of a second, with any remainder rounded up to the next whole tick.The two input datetime parameters can be any valid datatimes. If either or both input parameters are null, the function returns a null.The script creates the function, and runs a demo script to show the expected results. I have also included the results.I wrote this function as a general solution to the problem of finding the mean of two datetime values that was posted in this thread:How to display mean datetime with aggregates?http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=67968if objectproperty(object_id('dbo.F_DATETIME_RANGE_MIDPOINT'),'IsScalarFunction') = 1 begin drop function dbo.F_DATETIME_RANGE_MIDPOINT endgocreate function dbo.F_DATETIME_RANGE_MIDPOINT ( @start datetime, @end datetime )returns datetimeas/*Function: F_DATETIME_RANGE_MIDPOINT Computes the midpoint in time between two input parameter datetime values, @start and @end, and returns the midpoint as a datetime. The midpoint result is accurate to the nearest clock tick of 1/300 of a second, with any remainder rounded up to the next whole tick. This function is valid for the entire range of datetime from 1753-01-01 00:00:00.000 through 9999-12-31 23:59:59.997 This function returns the same result, no matter what order the input parameters are passed. This function returns null if either or both input parameters are null. Usage: select Midpoint = dbo.F_DATETIME_RANGE_MIDPOINT('20060101', '20060102')*/begindeclare @st datetimedeclare @et datetimedeclare @hours intdeclare @ms intdeclare @ticks intdeclare @ms_half int-- Set order of input parameters so that return value is always-- the same no matter what order the input values are passed.if @start > @end select @st = @end, @et = @startelse select @st = @start, @et = @end-- Get hours boundary difference.-- Subtract 1 from diff, before dividing by 2 and multiplying by 2-- so the milliseconds remaining is always positive and-- hours is always >= zero and evenly divisible by 2.set @hours = ((datediff(hh,@st,@et)-1)/2)*2-- Get remainder millisecondsset @ms = datediff(ms,0,@et-dateadd(hh,@hours,@st))-- Convert remainder milliseconds to-- SQL Server 'clock ticks' of 1/300 of a secondset @ticks = ((@ms/10)*3) + ((@ms%10)/3)-- Divide 'clock ticks' by 2, -- and round up ( 9/2 = 4.5 , so round up to 5)-- to follow the usual rounding rulesset @ticks = (@ticks/2) + (@ticks%2)-- Convert clock ticks back to millisecondsselect @ms_half = ((@ticks/3)*10) + floor(((@ticks%3)*3.5))-- Compute midpoint as:-- Add ( hours boundary difference / 2 ) hours to start time-- Then add (remainder milliseconds / 2 ) to result of prior stepreturn dateadd(ms,@ms_half,dateadd(hh,@hours/2,@st))endgoselect Midpoint = convert(varchar(23),dbo.F_DATETIME_RANGE_MIDPOINT( a.ST, a.ET ) ,121) , [Start] = convert(varchar(23),a.ST ,121) , [End] = convert(varchar(23),a.ET ,121) , a.Commentfrom(select ST = getdate(), ET = getdate()+2 , Comment = 'Now thru 2 days from now' union allselect '20060101', '20060102' , 'One day diff' union allselect '20060102', '20060101' , 'One day diff reversed' union allselect '20060102 23:59:59.997', '20060103 23:59:59.997' ,'One day diff' union allselect '20060102', '20060103 00:00:00.020' ,'One day + 6 ticks' union allselect '20060102', '20060103 00:00:00.017' ,'One day + 5 ticks' union allselect '20060102', '20060103 00:00:00.013' ,'One day + 4 ticks' union allselect '20060102', '20060103 00:00:00.010' ,'One day + 3 ticks' union allselect '20060102', '20060103 00:00:00.007' ,'One day + 2 ticks' union allselect '20060102', '20060103 00:00:00.003' ,'One day + 1 tick' union allselect '20060102', '20060103 00:00:00.000' ,'One day + 0 tick' union allselect '20060102', '20060102 23:59:59.997' ,'One day - 1 tick' union allselect '20060102', '20060102 23:59:59.993' ,'One day - 2 ticks' union allselect '20060102', '20060102 23:59:59.990' ,'One day - 3 ticks' union allselect '20060102', '20060102 23:59:59.987' ,'One day - 4 ticks' union allselect '20060102', '20060102 23:59:59.983' ,'One day - 5 ticks' union allselect '20060102', '20060102 23:59:59.980' ,'One day - 6 ticks' union allselect '20030101', '20030101' ,'Both times same' union allselect '20030101', '20030108' ,'One week diff' union allselect '20021228', '20030104' ,'One week diff' union allselect '20010701', '20010713' ,'12 day diff' union allselect '20010701', '20010714' ,'13 day diff' union allselect '20010630', '20010713' ,'13 day diff' union allselect '19901201 01:00:00.000', '19901201 02:00:00.000' ,'1 hour diff' union allselect '19901201 01:00:33.003', '19901201 02:00:33.003' ,'1 hour diff' union allselect '19901201 01:00:00.000', '19901201 01:30:00.000' ,'30 min diff' union allselect '19901201 01:00:33.447', '19901201 01:30:33.447' ,'30 min diff' union allselect '19901201 01:00:00.000', '19901201 01:05:00.000' ,'5 min diff' union allselect '19901201 01:00:29.123', '19901201 01:05:29.123' ,'5 min diff' union allselect '19901201 01:00:00.000', '19901201 01:01:00.000' ,'1 min diff' union allselect '19901201 01:00:00.000', '19901201 01:00:01.000' ,'1 sec diff' union allselect '19901201 01:00:00.000', '19901201 01:00:00.100' ,'100 ms diff' union allselect '19901201 01:00:00.000', '19901201 01:00:00.050' ,'50 ms diff' union allselect '19901201 01:00:00.000', '19901201 01:00:00.023' ,'23 ms diff' union allselect '19901201 01:00:00.000', '19901201 01:00:00.020' ,'20 ms diff' union allselect '19901201 01:00:00.000', '19901201 01:00:00.013' ,'13 ms diff' union allselect '19901201 01:00:00.000', '19901201 01:00:00.010' ,'10 ms diff' union allselect '19901201 01:00:00.000', '19901201 01:00:00.007' ,'7 ms diff' union allselect '19901201 01:00:00.000', '19901201 01:00:00.003' ,'3 ms diff' union allselect '20030101', '20030201' ,'One month diff 31 days' union allselect '20030101', '20030201' ,'One month diff 30 days' union allselect '20040201', '20040301' ,'One month diff 29 days' union allselect '20030201', '20030301' ,'One month diff 28 days' union allselect '20030101', '20040101' ,'One year diff' union allselect '20040101', '20050101' ,'One year diff leap year' union allselect '20050101', '20070101' ,'Two year diff' union allselect '20040101', '20060101' ,'Two year diff with leap year 1st' union allselect '20030101', '20050101' ,'Two year diff with leap year 2nd' union allselect '20060101', '20060301' ,'2 month diff' union allselect '20040101', '20040301' ,'2 month diff leap year' union allselect null, '20060101' ,'Start time null' union allselect '20060102', null ,'End time null' union allselect null, null ,'Both null' union allselect '17530101', '99991231 23:59:59.997' ,'Max datetime diff' union allselect '99991231 23:59:59.997','17530101' ,'Max datetime diff reversed') a
Results:Midpoint Start End Comment ----------------------- ----------------------- ----------------------- -------------------------------- 2006-07-10 17:12:24.300 2006-07-09 17:12:24.300 2006-07-11 17:12:24.300 Now thru 2 days from now2006-01-01 12:00:00.000 2006-01-01 00:00:00.000 2006-01-02 00:00:00.000 One day diff2006-01-01 12:00:00.000 2006-01-02 00:00:00.000 2006-01-01 00:00:00.000 One day diff reversed2006-01-03 11:59:59.997 2006-01-02 23:59:59.997 2006-01-03 23:59:59.997 One day diff2006-01-02 12:00:00.010 2006-01-02 00:00:00.000 2006-01-03 00:00:00.020 One day + 6 ticks2006-01-02 12:00:00.010 2006-01-02 00:00:00.000 2006-01-03 00:00:00.017 One day + 5 ticks2006-01-02 12:00:00.007 2006-01-02 00:00:00.000 2006-01-03 00:00:00.013 One day + 4 ticks2006-01-02 12:00:00.007 2006-01-02 00:00:00.000 2006-01-03 00:00:00.010 One day + 3 ticks2006-01-02 12:00:00.003 2006-01-02 00:00:00.000 2006-01-03 00:00:00.007 One day + 2 ticks2006-01-02 12:00:00.003 2006-01-02 00:00:00.000 2006-01-03 00:00:00.003 One day + 1 tick2006-01-02 12:00:00.000 2006-01-02 00:00:00.000 2006-01-03 00:00:00.000 One day + 0 tick2006-01-02 12:00:00.000 2006-01-02 00:00:00.000 2006-01-02 23:59:59.997 One day - 1 tick2006-01-02 11:59:59.997 2006-01-02 00:00:00.000 2006-01-02 23:59:59.993 One day - 2 ticks2006-01-02 11:59:59.997 2006-01-02 00:00:00.000 2006-01-02 23:59:59.990 One day - 3 ticks2006-01-02 11:59:59.993 2006-01-02 00:00:00.000 2006-01-02 23:59:59.987 One day - 4 ticks2006-01-02 11:59:59.993 2006-01-02 00:00:00.000 2006-01-02 23:59:59.983 One day - 5 ticks2006-01-02 11:59:59.990 2006-01-02 00:00:00.000 2006-01-02 23:59:59.980 One day - 6 ticks2003-01-01 00:00:00.000 2003-01-01 00:00:00.000 2003-01-01 00:00:00.000 Both times same2003-01-04 12:00:00.000 2003-01-01 00:00:00.000 2003-01-08 00:00:00.000 One week diff2002-12-31 12:00:00.000 2002-12-28 00:00:00.000 2003-01-04 00:00:00.000 One week diff2001-07-07 00:00:00.000 2001-07-01 00:00:00.000 2001-07-13 00:00:00.000 12 day diff2001-07-07 12:00:00.000 2001-07-01 00:00:00.000 2001-07-14 00:00:00.000 13 day diff2001-07-06 12:00:00.000 2001-06-30 00:00:00.000 2001-07-13 00:00:00.000 13 day diff1990-12-01 01:30:00.000 1990-12-01 01:00:00.000 1990-12-01 02:00:00.000 1 hour diff1990-12-01 01:30:33.003 1990-12-01 01:00:33.003 1990-12-01 02:00:33.003 1 hour diff1990-12-01 01:15:00.000 1990-12-01 01:00:00.000 1990-12-01 01:30:00.000 30 min diff1990-12-01 01:15:33.447 1990-12-01 01:00:33.447 1990-12-01 01:30:33.447 30 min diff1990-12-01 01:02:30.000 1990-12-01 01:00:00.000 1990-12-01 01:05:00.000 5 min diff1990-12-01 01:02:59.123 1990-12-01 01:00:29.123 1990-12-01 01:05:29.123 5 min diff1990-12-01 01:00:30.000 1990-12-01 01:00:00.000 1990-12-01 01:01:00.000 1 min diff1990-12-01 01:00:00.500 1990-12-01 01:00:00.000 1990-12-01 01:00:01.000 1 sec diff1990-12-01 01:00:00.050 1990-12-01 01:00:00.000 1990-12-01 01:00:00.100 100 ms diff1990-12-01 01:00:00.027 1990-12-01 01:00:00.000 1990-12-01 01:00:00.050 50 ms diff1990-12-01 01:00:00.013 1990-12-01 01:00:00.000 1990-12-01 01:00:00.023 23 ms diff1990-12-01 01:00:00.010 1990-12-01 01:00:00.000 1990-12-01 01:00:00.020 20 ms diff1990-12-01 01:00:00.007 1990-12-01 01:00:00.000 1990-12-01 01:00:00.013 13 ms diff1990-12-01 01:00:00.007 1990-12-01 01:00:00.000 1990-12-01 01:00:00.010 10 ms diff1990-12-01 01:00:00.003 1990-12-01 01:00:00.000 1990-12-01 01:00:00.007 7 ms diff1990-12-01 01:00:00.003 1990-12-01 01:00:00.000 1990-12-01 01:00:00.003 3 ms diff2003-01-16 12:00:00.000 2003-01-01 00:00:00.000 2003-02-01 00:00:00.000 One month diff 31 days2003-01-16 12:00:00.000 2003-01-01 00:00:00.000 2003-02-01 00:00:00.000 One month diff 30 days2004-02-15 12:00:00.000 2004-02-01 00:00:00.000 2004-03-01 00:00:00.000 One month diff 29 days2003-02-15 00:00:00.000 2003-02-01 00:00:00.000 2003-03-01 00:00:00.000 One month diff 28 days2003-07-02 12:00:00.000 2003-01-01 00:00:00.000 2004-01-01 00:00:00.000 One year diff2004-07-02 00:00:00.000 2004-01-01 00:00:00.000 2005-01-01 00:00:00.000 One year diff leap year2006-01-01 00:00:00.000 2005-01-01 00:00:00.000 2007-01-01 00:00:00.000 Two year diff2004-12-31 12:00:00.000 2004-01-01 00:00:00.000 2006-01-01 00:00:00.000 Two year diff with leap year 1st2004-01-01 12:00:00.000 2003-01-01 00:00:00.000 2005-01-01 00:00:00.000 Two year diff with leap year 2nd2006-01-30 12:00:00.000 2006-01-01 00:00:00.000 2006-03-01 00:00:00.000 2 month diff2004-01-31 00:00:00.000 2004-01-01 00:00:00.000 2004-03-01 00:00:00.000 2 month diff leap yearNULL NULL 2006-01-01 00:00:00.000 Start time nullNULL 2006-01-02 00:00:00.000 NULL End time nullNULL NULL NULL Both null5876-07-02 00:00:00.000 1753-01-01 00:00:00.000 9999-12-31 23:59:59.997 Max datetime diff5876-07-02 00:00:00.000 9999-12-31 23:59:59.997 1753-01-01 00:00:00.000 Max datetime diff reversed(55 row(s) affected)
CODO ERGO SUM