Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)
7020 Posts |
Posted - 2006-04-15 : 14:28:46
|
There are a lot of questions posted on SQLTEAM asking how to find the beginning of various time periods. The script will create and demo 14 functions that return a datetime for the beginning of a time period relative to the datetime value passed in parameter @DAY.I put together this script to create these functions for several reasons:1. To allow people to find them on their own without having to post a question.2. To allow posted questions to be answered with a reference to this script. 3. To document algorithms that work for the widest possible range of datetime values. All except for the Century and Decade functions work for any datetime value from 1753/01/01 00:00:00.000 through 9999/12/31 23:59:59.997. The Century is limited to datetimes from 1800/01/01 forward, because 1700/01/01 is not valid in SQL Server. The Decade function is limited to datetimes from 1760/01/01 forward, because 1750/01/01 is not valid in SQL Server.4. And last, you can actually use them on your application. The function names created by this script are:dbo.F_START_OF_CENTURY( @DAY )dbo.F_START_OF_DECADE( @DAY )dbo.F_START_OF_YEAR( @DAY )dbo.F_START_OF_QUARTER( @DAY )dbo.F_START_OF_MONTH( @DAY )dbo.F_START_OF_DAY( @DAY )dbo.F_START_OF_HOUR( @DAY )dbo.F_START_OF_30_MIN( @DAY )dbo.F_START_OF_20_MIN( @DAY )dbo.F_START_OF_15_MIN( @DAY )dbo.F_START_OF_10_MIN( @DAY )dbo.F_START_OF_05_MIN( @DAY )dbo.F_START_OF_X_MIN( @DAY )dbo.F_START_OF_MINUTE( @DAY )dbo.F_START_OF_SECOND( @DAY )There is a separate post for function dbo.F_START_OF_WEEK to find the first day of the week at this link:http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=47307This script was tested with SQL Server 2000 only.I posted a script for End Date of Time Period Functions here:http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=64759Other Date/Time Info and Script Links:http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=64762Edit 2006-11-01:Added dbo.F_START_OF_X_MIN( @DAY ) at the suggestion of Peter.Edit 2007-02-24:Modified the following functions to use a simpler algorithm, that is shorter, runs faster, and is more suited for use with in-line code:dbo.F_START_OF_30_MIN( @DAY )dbo.F_START_OF_20_MIN( @DAY )dbo.F_START_OF_15_MIN( @DAY )dbo.F_START_OF_10_MIN( @DAY )dbo.F_START_OF_05_MIN( @DAY )Edit 2009-03-24:Added script at end to demo start of time period methods using in-line code, along with output from sample script./*Functions created by this script: dbo.F_START_OF_CENTURY( @DAY ) dbo.F_START_OF_DECADE( @DAY ) dbo.F_START_OF_YEAR( @DAY ) dbo.F_START_OF_QUARTER( @DAY ) dbo.F_START_OF_MONTH( @DAY ) dbo.F_START_OF_DAY( @DAY ) dbo.F_START_OF_HOUR( @DAY ) dbo.F_START_OF_30_MIN( @DAY ) dbo.F_START_OF_20_MIN( @DAY ) dbo.F_START_OF_15_MIN( @DAY ) dbo.F_START_OF_10_MIN( @DAY ) dbo.F_START_OF_05_MIN( @DAY ) dbo.F_START_OF_MINUTE( @DAY ) dbo.F_START_OF_SECOND( @DAY )*/goif objectproperty(object_id('dbo.F_START_OF_CENTURY'),'IsScalarFunction') = 1 begin drop function dbo.F_START_OF_CENTURY endgocreate function dbo.F_START_OF_CENTURY ( @DAY datetime )returns datetimeas/*Function: F_START_OF_CENTURY Finds start of first day of century at 00:00:00.000 for input datetime, @DAY. Valid for all SQL Server datetimes >= 1800-01-01 00:00:00.000 Returns null if @DAY < 1800-01-01 00:00:00.000*/begindeclare @BASE_DAY datetimeselect @BASE_DAY = '18000101'IF @DAY < @BASE_DAY return null return dateadd(yy,(datediff(yy,@BASE_DAY,@DAY)/100)*100,@BASE_DAY) endgoif objectproperty(object_id('dbo.F_START_OF_DECADE'),'IsScalarFunction') = 1 begin drop function dbo.F_START_OF_DECADE endgocreate function dbo.F_START_OF_DECADE ( @DAY datetime )returns datetimeas/*Function: F_START_OF_DECADE Finds start of first day of decade at 00:00:00.000 for input datetime, @DAY. Valid for all SQL Server datetimes >= 1760-01-01 00:00:00.000 Returns null if @DAY < 1760-01-01 00:00:00.000*/begindeclare @BASE_DAY datetimeselect @BASE_DAY = '17600101'IF @DAY < @BASE_DAY return null return dateadd(yy,(datediff(yy,@BASE_DAY,@DAY)/10)*10,@BASE_DAY) endgoif objectproperty(object_id('dbo.F_START_OF_YEAR'),'IsScalarFunction') = 1 begin drop function dbo.F_START_OF_YEAR endgocreate function dbo.F_START_OF_YEAR ( @DAY datetime )returns datetimeas/*Function: F_START_OF_YEAR Finds start of first day of year at 00:00:00.000 for input datetime, @DAY. Valid for all SQL Server datetimes.*/beginreturn dateadd(yy,datediff(yy,0,@DAY),0)endgoif objectproperty(object_id('dbo.F_START_OF_QUARTER'),'IsScalarFunction') = 1 begin drop function dbo.F_START_OF_QUARTER endgocreate function dbo.F_START_OF_QUARTER ( @DAY datetime )returns datetimeas/*Function: F_START_OF_QUARTER Finds start of first day of quarter at 00:00:00.000 for input datetime, @DAY. Valid for all SQL Server datetimes.*/beginreturn dateadd(qq,datediff(qq,0,@DAY),0)endgoif objectproperty(object_id('dbo.F_START_OF_MONTH'),'IsScalarFunction') = 1 begin drop function dbo.F_START_OF_MONTH endgocreate function dbo.F_START_OF_MONTH ( @DAY datetime )returns datetimeas/*Function: F_START_OF_MONTH Finds start of first day of month at 00:00:00.000 for input datetime, @DAY. Valid for all SQL Server datetimes.*/beginreturn dateadd(mm,datediff(mm,0,@DAY),0)endgoif objectproperty(object_id('dbo.F_START_OF_DAY'),'IsScalarFunction') = 1 begin drop function dbo.F_START_OF_DAY endgocreate function dbo.F_START_OF_DAY ( @DAY datetime )returns datetimeas/*Function: F_START_OF_DAY Finds start of day at 00:00:00.000 for input datetime, @DAY. Valid for all SQL Server datetimes*/beginreturn dateadd(dd,datediff(dd,0,@DAY),0)endgoif objectproperty(object_id('dbo.F_START_OF_HOUR'),'IsScalarFunction') = 1 begin drop function dbo.F_START_OF_HOUR endgocreate function dbo.F_START_OF_HOUR ( @DAY datetime )returns datetimeas/*Function: F_START_OF_HOUR Finds beginning of hour for input datetime, @DAY. Valid for all SQL Server datetimes.*/beginreturn dateadd(hh,datediff(hh,0,@DAY),0)endgoif objectproperty(object_id('dbo.F_START_OF_30_MIN'),'IsScalarFunction') = 1 begin drop function dbo.F_START_OF_30_MIN endgocreate function dbo.F_START_OF_30_MIN ( @DAY datetime )returns datetimeas/*Function: F_START_OF_30_MIN Finds beginning of 30 minute period for input datetime, @DAY. Valid for all SQL Server datetimes.*/beginreturn dateadd(mi,(datepart(mi,@Day)/30)*30,dateadd(hh,datediff(hh,0,@Day),0))endgoif objectproperty(object_id('dbo.F_START_OF_20_MIN'),'IsScalarFunction') = 1 begin drop function dbo.F_START_OF_20_MIN endgocreate function dbo.F_START_OF_20_MIN ( @DAY datetime )returns datetimeas/*Function: F_START_OF_20_MIN Finds beginning of 20 minute period for input datetime, @DAY. Valid for all SQL Server datetimes.*/beginreturn dateadd(mi,(datepart(mi,@Day)/20)*20,dateadd(hh,datediff(hh,0,@Day),0))endgoif objectproperty(object_id('dbo.F_START_OF_15_MIN'),'IsScalarFunction') = 1 begin drop function dbo.F_START_OF_15_MIN endgocreate function dbo.F_START_OF_15_MIN ( @DAY datetime )returns datetimeas/*Function: F_START_OF_15_MIN Finds beginning of 15 minute period for input datetime, @DAY. Valid for all SQL Server datetimes.*/beginreturn dateadd(mi,(datepart(mi,@Day)/15)*15,dateadd(hh,datediff(hh,0,@Day),0))endgoif objectproperty(object_id('dbo.F_START_OF_10_MIN'),'IsScalarFunction') = 1 begin drop function dbo.F_START_OF_10_MIN endgocreate function dbo.F_START_OF_10_MIN ( @DAY datetime )returns datetimeas/*Function: F_START_OF_10_MIN Finds beginning of 10 minute period for input datetime, @DAY. Valid for all SQL Server datetimes.*/beginreturn dateadd(mi,(datepart(mi,@Day)/10)*10,dateadd(hh,datediff(hh,0,@Day),0))endgoif objectproperty(object_id('dbo.F_START_OF_05_MIN'),'IsScalarFunction') = 1 begin drop function dbo.F_START_OF_05_MIN endgocreate function dbo.F_START_OF_05_MIN ( @DAY datetime )returns datetimeas/*Function: F_START_OF_05_MIN Finds beginning of 5 minute period for input datetime, @DAY. Valid for all SQL Server datetimes.*/beginreturn dateadd(mi,(datepart(mi,@Day)/5)*5,dateadd(hh,datediff(hh,0,@Day),0))endgoif objectproperty(object_id('dbo.F_START_OF_X_MIN'),'IsScalarFunction') = 1 begin drop function dbo.F_START_OF_X_MIN endgocreate function dbo.F_START_OF_X_MIN ( @DAY datetime, @INTERVAL int )returns datetimeas/*Function: F_START_OF_X_MIN Finds beginning of @INTERVAL minute period for input datetime, @DAY. If @INTERVAL = zero, returns @DAY. Valid for all SQL Server datetimes.*/begin-- Prevent divide by zero errorif @INTERVAL = 0 return @DAYdeclare @BASE_DAY datetimeset @BASE_DAY = dateadd(dd,datediff(dd,0,@Day),0)return dateadd(mi,(datediff(mi,@BASE_DAY,@Day)/@INTERVAL)*@INTERVAL,@BASE_DAY)endgoif objectproperty(object_id('dbo.F_START_OF_MINUTE'),'IsScalarFunction') = 1 begin drop function dbo.F_START_OF_MINUTE endgocreate function dbo.F_START_OF_MINUTE ( @DAY datetime )returns datetimeas/*Function: F_START_OF_MINUTE Finds beginning of minute for input datetime, @DAY. Valid for all SQL Server datetimes.*/beginreturn dateadd(ms,-(datepart(ss,@DAY)*1000)-datepart(ms,@DAY),@DAY)endgoif objectproperty(object_id('dbo.F_START_OF_SECOND'),'IsScalarFunction') = 1 begin drop function dbo.F_START_OF_SECOND endgocreate function dbo.F_START_OF_SECOND ( @DAY datetime )returns datetimeas/*Function: F_START_OF_SECOND Finds beginning of second for input datetime, @DAY. Valid for all SQL Server datetimes.*/beginreturn dateadd(ms,-datepart(ms,@DAY),@DAY)endgo/*Start of test scriptLoad dates to test F_START_OF functions*/declare @test_dates table ( DT datetime not null primary key clustered )declare @today varchar(10)select @today = convert(varchar(10),getdate(),112)declare @year varchar(4)select @year = convert(varchar(4),year(getdate()))declare @lyear varchar(10)select @lyear = convert(varchar(10),getdate()-345,112)insert into @test_dates (DT)select DT = getdate() union allselect '17530101 00:00:00.000' union all-- Test start of Decade cutoffselect '17591231 23:59:59.997' union allselect '17600101 23:04:59.997' union all-- Test start of Century cutoffselect '17991231 23:59:59.997' union allselect '18000101 00:00:00.000' union all-- Test start of Decade and Centuryselect '19000101 00:00:00.000' union allselect '19001231 23:59:59.997' union allselect '19400101 00:00:00.000' union allselect '19491231 23:59:59.997' union allselect '19900101 00:00:00.000' union allselect '19991231 23:59:59.997' union all-- For start of Hour testingselect @lyear+' 00:00:00.000' union allselect @lyear+' 00:59:59.997' union allselect @lyear+' 01:00:00.000' union allselect @lyear+' 01:59:59.997' union allselect @lyear+' 12:00:00.000' union allselect @lyear+' 12:59:59.997' union allselect @lyear+' 17:00:00.000' union allselect @lyear+' 17:59:59.997' union allselect @lyear+' 23:00:00.000' union allselect @lyear+' 23:59:59.997' union all-- For start of Month, Quarter, and Year testingselect @year+'0101 00:00:00.000' union allselect @year+'0131 23:59:59.997' union allselect @year+'0201 00:00:00.000' union allselect @year+'0228 23:59:59.997' union allselect @year+'0301 00:00:00.000' union allselect @year+'0331 23:59:59.997' union allselect @year+'0401 00:00:00.000' union allselect @year+'0430 23:59:59.997' union allselect @year+'0501 00:00:00.000' union allselect @year+'0531 23:59:59.997' union allselect @year+'0601 00:00:00.000' union allselect @year+'0630 23:59:59.997' union allselect @year+'0701 00:00:00.000' union allselect @year+'0731 23:59:59.997' union allselect @year+'0801 00:00:00.000' union allselect @year+'0831 23:59:59.997' union allselect @year+'0901 00:00:00.000' union allselect @year+'0930 23:59:59.997' union allselect @year+'1001 00:00:00.000' union allselect @year+'1031 23:59:59.997' union allselect @year+'1101 00:00:00.000' union allselect @year+'1130 23:59:59.997' union allselect @year+'1201 00:00:00.000' union allselect @year+'1231 23:59:59.997' union all-- Test start of 5, 10, 15, 20, and 30 min testing select @today+' 23:04:59.997' union allselect @today+' 23:09:59.997' union allselect @today+' 23:14:59.997' union allselect @today+' 23:19:59.997' union allselect @today+' 23:24:59.997' union allselect @today+' 23:29:59.997' union allselect @today+' 23:34:59.997' union allselect @today+' 23:39:59.997' union allselect @today+' 23:44:59.997' union allselect @today+' 23:49:59.997' union allselect @today+' 23:54:59.997' union allselect @today+' 23:59:59.997' union allselect '99991231 23:59:59.997'order by 1-- Convert dates in @test_dates table to test F_START_OF functionsselect TYPE = 'CENTURY' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_START_OF_CENTURY( DT ),121)from @test_datesorder by DTselect TYPE = 'DECADE' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_START_OF_DECADE( DT ),121)from @test_datesorder by DTselect TYPE = 'YEAR' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_START_OF_YEAR( DT ),121)from @test_datesorder by DTselect TYPE = 'QUARTER' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_START_OF_QUARTER( DT ),121)from @test_datesorder by DTselect TYPE = 'MONTH' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_START_OF_MONTH( DT ),121)from @test_datesorder by DTselect TYPE = 'DAY' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_START_OF_DAY( DT ),121)from @test_datesorder by DTselect TYPE = 'HOUR' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_START_OF_HOUR( DT ),121)from @test_datesorder by DTselect TYPE = '30_MIN' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_START_OF_30_MIN( DT ),121)from @test_datesorder by DTselect TYPE = '20_MIN' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_START_OF_20_MIN( DT ),121)from @test_datesorder by DTselect TYPE = '15_MIN' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_START_OF_15_MIN( DT ),121)from @test_datesorder by DTselect TYPE = '10_MIN' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_START_OF_10_MIN( DT ),121)from @test_datesorder by DTselect TYPE = '05_MIN' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_START_OF_05_MIN( DT ),121)from @test_datesorder by DTselect TYPE = 'MINUTE' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_START_OF_MINUTE( DT ),121)from @test_datesorder by DTselect TYPE = 'SECOND' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_START_OF_SECOND( DT ),121)from @test_datesorder by DT/*End of test script*/ /*Script to demo Start of Time period methods in-line for various types of time periods.All methods will run with no error for any valid datetime value*/set nocount ondeclare @day table (DT datetime not null primary key clustered)-- Load Test Datesinsert into @day (DT)select DT = getdate()union allselect '2014-05-24 16:56:27.667'union allselect '17530101 00:00:00.000'union allselect '17591231 23:59:59.997'union allselect '17600101 00:00:00.000'union allselect '17991231 23:59:59.997'union allselect '18000101 00:00:00.000'union allselect '99991231 23:59:59.997'order by 1select Test_Dates = DT from @day order by 1select START_OF_CENTURY = case when a.DT < '18000101' then convert(datetime,null) else dateadd(yy,(datediff(yy,'18000101',a.DT)/100)*100,'18000101') endfrom @day aselect START_OF_DECADE = case when a.DT < '17600101' then convert(datetime,null) else dateadd(yy,(datediff(yy,'17600101',a.DT)/10)*10,'17600101') endfrom @day aselect START_OF_YEAR = dateadd(yy,datediff(yy,0,a.DT),0) from @day aselect START_OF_QUARTER = dateadd(qq,datediff(qq,0,a.DT),0) from @day aselect START_OF_MONTH = dateadd(mm,datediff(mm,0,a.DT),0) from @day aselect START_OF_DAY = dateadd(dd,datediff(dd,0,a.DT),0) from @day aselect START_OF_HOUR = dateadd(hh,datediff(hh,0,a.DT),0) from @day aselect START_OF_30_MIN = dateadd(mi,(datepart(mi,a.DT)/30)*30,dateadd(hh,datediff(hh,0,a.DT),0)) from @day aselect START_OF_20_MIN = dateadd(mi,(datepart(mi,a.DT)/20)*20,dateadd(hh,datediff(hh,0,a.DT),0)) from @day aselect START_OF_15_MIN = dateadd(mi,(datepart(mi,a.DT)/15)*15,dateadd(hh,datediff(hh,0,a.DT),0)) from @day aselect START_OF_10_MIN = dateadd(mi,(datepart(mi,a.DT)/10)*10,dateadd(hh,datediff(hh,0,a.DT),0)) from @day aselect START_OF_05_MIN = dateadd(mi,(datepart(mi,a.DT)/5)*5,dateadd(hh,datediff(hh,0,a.DT),0)) from @day aselect START_OF_MINUTE = dateadd(ms,-(datepart(ss,a.DT)*1000)-datepart(ms,a.DT),a.DT) from @day aselect START_OF_SECOND = dateadd(ms,-datepart(ms,a.DT),a.DT) from @day a Results for in-line code demo:Test_Dates ------------------------------------------------------ 1753-01-01 00:00:00.0001759-12-31 23:59:59.9971760-01-01 00:00:00.0001799-12-31 23:59:59.9971800-01-01 00:00:00.0002009-03-24 17:03:53.7172014-05-24 16:56:27.6679999-12-31 23:59:59.997START_OF_CENTURY ------------------------------------------------------ NULLNULLNULLNULL1800-01-01 00:00:00.0002000-01-01 00:00:00.0002000-01-01 00:00:00.0009900-01-01 00:00:00.000START_OF_DECADE ------------------------------------------------------ NULLNULL1760-01-01 00:00:00.0001790-01-01 00:00:00.0001800-01-01 00:00:00.0002000-01-01 00:00:00.0002010-01-01 00:00:00.0009990-01-01 00:00:00.000START_OF_YEAR ------------------------------------------------------ 1753-01-01 00:00:00.0001759-01-01 00:00:00.0001760-01-01 00:00:00.0001799-01-01 00:00:00.0001800-01-01 00:00:00.0002009-01-01 00:00:00.0002014-01-01 00:00:00.0009999-01-01 00:00:00.000START_OF_QUARTER ------------------------------------------------------ 1753-01-01 00:00:00.0001759-10-01 00:00:00.0001760-01-01 00:00:00.0001799-10-01 00:00:00.0001800-01-01 00:00:00.0002009-01-01 00:00:00.0002014-04-01 00:00:00.0009999-10-01 00:00:00.000START_OF_MONTH ------------------------------------------------------ 1753-01-01 00:00:00.0001759-12-01 00:00:00.0001760-01-01 00:00:00.0001799-12-01 00:00:00.0001800-01-01 00:00:00.0002009-03-01 00:00:00.0002014-05-01 00:00:00.0009999-12-01 00:00:00.000START_OF_DAY ------------------------------------------------------ 1753-01-01 00:00:00.0001759-12-31 00:00:00.0001760-01-01 00:00:00.0001799-12-31 00:00:00.0001800-01-01 00:00:00.0002009-03-24 00:00:00.0002014-05-24 00:00:00.0009999-12-31 00:00:00.000START_OF_HOUR ------------------------------------------------------ 1753-01-01 00:00:00.0001759-12-31 23:00:00.0001760-01-01 00:00:00.0001799-12-31 23:00:00.0001800-01-01 00:00:00.0002009-03-24 17:00:00.0002014-05-24 16:00:00.0009999-12-31 23:00:00.000START_OF_30_MIN ------------------------------------------------------ 1753-01-01 00:00:00.0001759-12-31 23:30:00.0001760-01-01 00:00:00.0001799-12-31 23:30:00.0001800-01-01 00:00:00.0002009-03-24 17:00:00.0002014-05-24 16:30:00.0009999-12-31 23:30:00.000START_OF_20_MIN ------------------------------------------------------ 1753-01-01 00:00:00.0001759-12-31 23:40:00.0001760-01-01 00:00:00.0001799-12-31 23:40:00.0001800-01-01 00:00:00.0002009-03-24 17:00:00.0002014-05-24 16:40:00.0009999-12-31 23:40:00.000START_OF_15_MIN ------------------------------------------------------ 1753-01-01 00:00:00.0001759-12-31 23:45:00.0001760-01-01 00:00:00.0001799-12-31 23:45:00.0001800-01-01 00:00:00.0002009-03-24 17:00:00.0002014-05-24 16:45:00.0009999-12-31 23:45:00.000START_OF_10_MIN ------------------------------------------------------ 1753-01-01 00:00:00.0001759-12-31 23:50:00.0001760-01-01 00:00:00.0001799-12-31 23:50:00.0001800-01-01 00:00:00.0002009-03-24 17:00:00.0002014-05-24 16:50:00.0009999-12-31 23:50:00.000START_OF_05_MIN ------------------------------------------------------ 1753-01-01 00:00:00.0001759-12-31 23:55:00.0001760-01-01 00:00:00.0001799-12-31 23:55:00.0001800-01-01 00:00:00.0002009-03-24 17:00:00.0002014-05-24 16:55:00.0009999-12-31 23:55:00.000START_OF_MINUTE ------------------------------------------------------ 1753-01-01 00:00:00.0001759-12-31 23:59:00.0001760-01-01 00:00:00.0001799-12-31 23:59:00.0001800-01-01 00:00:00.0002009-03-24 17:03:00.0002014-05-24 16:56:00.0009999-12-31 23:59:00.000START_OF_SECOND ------------------------------------------------------ 1753-01-01 00:00:00.0001759-12-31 23:59:59.0001760-01-01 00:00:00.0001799-12-31 23:59:59.0001800-01-01 00:00:00.0002009-03-24 17:03:53.0002014-05-24 16:56:27.0009999-12-31 23:59:59.000 CODO ERGO SUM |
|
CLages
Posting Yak Master
116 Posts |
Posted - 2006-10-24 : 15:11:05
|
The main problem is thatAlways i convert to SMALLDATETIME, the CONVERT round the Date, I needto Truncate.I can not Now change the Column from smalldatetime to datetimetksClages |
|
|
rockmoose
SQL Natt Alfen
3279 Posts |
Posted - 2006-10-24 : 15:28:46
|
I only miss:F_DANCERS_AT_THE_END_OF_TIME()rockmoose |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2006-11-01 : 07:54:21
|
What about dbo.F_START_OF_X_MIN( @DAY, @Interval ) ? Then divide and multiply with @Interval?I needed this function, today, so I took the liberty to write the function as F_START_OF_6_MIN, because I needed to calculate to a 1/10th of an hour.Then I realized the function could accept this interval as a parameter.Peter LarssonHelsingborg, Sweden |
|
|
Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)
7020 Posts |
Posted - 2006-11-01 : 16:25:21
|
quote: Originally posted by Peso What about dbo.F_START_OF_X_MIN( @DAY, @Interval ) ? Then divide and multiply with @Interval?I needed this function, today, so I took the liberty to write the function as F_START_OF_6_MIN, because I needed to calculate to a 1/10th of an hour.Then I realized the function could accept this interval as a parameter.Peter LarssonHelsingborg, Sweden
Added F_START_OF_X_MIN to script.CODO ERGO SUM |
|
|
Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)
7020 Posts |
Posted - 2007-02-24 : 19:03:55
|
Modified the following functions to use a simpler algorithm, that is shorter, runs faster, and is more suited for use with in-line code:dbo.F_START_OF_30_MIN( @DAY )dbo.F_START_OF_20_MIN( @DAY )dbo.F_START_OF_15_MIN( @DAY )dbo.F_START_OF_10_MIN( @DAY )dbo.F_START_OF_05_MIN( @DAY )CODO ERGO SUM |
|
|
rockmoose
SQL Natt Alfen
3279 Posts |
Posted - 2007-02-25 : 16:58:08
|
quote: Originally posted by Michael Valentine Jones Modified the following functions to use a simpler algorithm, that is shorter, runs faster, and is more suited for use with in-line code:dbo.F_START_OF_30_MIN( @DAY )dbo.F_START_OF_20_MIN( @DAY )dbo.F_START_OF_15_MIN( @DAY )dbo.F_START_OF_10_MIN( @DAY )dbo.F_START_OF_05_MIN( @DAY )CODO ERGO SUM
I don't know what the change was, but this seems even simpler?:declare @Day datetime; set @Day = getdate()select @day ,dateadd(mi,(datepart(mi,@Day)/15)*15,dateadd(hh,datediff(hh,0,@Day),0)) as mvj ,dateadd(mi,datediff(mi,0,@Day)-datepart(mi,@day)%15,0) as rockmoose |
|
|
Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)
7020 Posts |
Posted - 2007-02-25 : 18:13:29
|
quote: Originally posted by rockmooseI don't know what the change was, but this seems even simpler?:declare @Day datetime; set @Day = getdate()select @day ,dateadd(mi,(datepart(mi,@Day)/15)*15,dateadd(hh,datediff(hh,0,@Day),0)) as mvj ,dateadd(mi,datediff(mi,0,@Day)-datepart(mi,@day)%15,0) as rockmoose
The second method does work most of the time, but it doesn't meet my design objective to "work for any datetime value from 1753/01/01 00:00:00.000 through 9999/12/31 23:59:59.997"declare @day datetimeset @day = '99991231 23:59:59'print 'Method 1'select M1 = dateadd(mi,(datepart(mi,@Day)/15)*15,dateadd(hh,datediff(hh,0,@Day),0))print 'Method 2'select M2 = dateadd(mi,datediff(mi,0,@Day)-datepart(mi,@day)%15,0) Results:Method 1M1 ------------------------------------------------------ 9999-12-31 23:45:00.000(1 row(s) affected)Method 2Server: Msg 535, Level 16, State 1, Line 8Difference of two datetime columns caused overflow at runtime. CODO ERGO SUM |
|
|
rockmoose
SQL Natt Alfen
3279 Posts |
Posted - 2007-02-26 : 03:24:10
|
hmm, yes, it only works up to '5983-01-24 02:07:59.997'rockmoose |
|
|
Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)
7020 Posts |
Posted - 2007-02-26 : 09:41:03
|
quote: Originally posted by rockmoose hmm, yes, it only works up to '5983-01-24 02:07:59.997'rockmoose
The method you posted would work for the vast majority of applications, but I wanted an algorithm that would work with any datetime. My method is a little more complicated, but still possible to use with in-line code instead of in the function, and that is also something I wanted.The previous method was the one used in F_START_OF_X_MIN. I didn't change that function, because it would change the results it produces when 60%@INTERVAL <> 0.CODO ERGO SUM |
|
|
X002548
Not Just a Number
15586 Posts |
|
rockmoose
SQL Natt Alfen
3279 Posts |
Posted - 2007-02-26 : 14:12:40
|
Good design goal, and for a "library" function I would expect no less.If I need to store year 6000AD, chances are that I also would need 60000AD or 600000AD, so another datatype altogether might make sense Reminds me of the Y2K bug, I't hate to leave an inbuilt Y5983 bug! <- Pun> F_LENGTH_OF_LAP_DANCE That's great...Now we need:F_TIME_OF_MARGERITA() |
|
|
Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)
7020 Posts |
Posted - 2007-02-26 : 14:18:14
|
quote: Originally posted by rockmoose Good design goal, and for a "library" function I would expect no less.If I need to store year 6000AD, chances are that I also would need 60000AD or 600000AD, so another datatype altogether might make sense Reminds me of the Y2K bug, I't hate to leave an inbuilt Y5983 bug! <- Pun> F_LENGTH_OF_LAP_DANCE That's great...Now we need:F_TIME_OF_MARGERITA()
Nobody seems too worried about the SQL Server Y10K bug.I'm more interested in the F_START_OF_LAP_DANCE.CODO ERGO SUM |
|
|
rockmoose
SQL Natt Alfen
3279 Posts |
Posted - 2007-02-26 : 14:40:18
|
> Nobody seems too worried about the SQL Server Y10K bug.M$ has an army of consultants ready to tackle that one, and they are not the lea$t worried.F_START_OF_LAP_DANCE, hmm yeah, I'd like to see an optimal implementation |
|
|
|
|
|
|
|