This script will create and demo 5 functions that return a datetime for the beginning (00:00:00.000) of the last day of a time period relative to the datetime value passed in parameter @DAY.These functions work for any datetime value from 1753/01/01 00:00:00.000 through 9999/12/31 23:59:59.997.The function names created by this script are:dbo.F_END_OF_CENTURY( @DAY )dbo.F_END_OF_DECADE( @DAY )dbo.F_END_OF_YEAR( @DAY )dbo.F_END_OF_QUARTER( @DAY )dbo.F_END_OF_MONTH( @DAY )This script was tested with SQL Server 2000 only.I posted a script for End of Week function, F_END_OF_WEEK here:http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=64760This post is a companion to Start of Time Period Functions posted here:http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=64755/*Functions created by this script: dbo.F_END_OF_CENTURY( @DAY ) dbo.F_END_OF_DECADE( @DAY ) dbo.F_END_OF_YEAR( @DAY ) dbo.F_END_OF_QUARTER( @DAY ) dbo.F_END_OF_MONTH( @DAY )*/goif objectproperty(object_id('dbo.F_END_OF_CENTURY'),'IsScalarFunction') = 1 begin drop function dbo.F_END_OF_CENTURY endgocreate function dbo.F_END_OF_CENTURY ( @DAY datetime )returns datetimeas/*Function: F_END_OF_CENTURY Finds start of last day of century at 00:00:00.000 for input datetime, @DAY. Valid for all SQL Server datetimes*/beginreturn dateadd(yy,99-(year(@day)%100),dateadd(yy,datediff(yy,-1,@DAY),-1))endgoif objectproperty(object_id('dbo.F_END_OF_DECADE'),'IsScalarFunction') = 1 begin drop function dbo.F_END_OF_DECADE endgocreate function dbo.F_END_OF_DECADE ( @DAY datetime )returns datetimeas/*Function: F_END_OF_DECADE Finds start of last day of decade at 00:00:00.000 for input datetime, @DAY. Valid for all SQL Server datetimes*/beginreturn dateadd(yy,9-(year(@day)%10),dateadd(yy,datediff(yy,-1,@DAY),-1))endgoif objectproperty(object_id('dbo.F_END_OF_YEAR'),'IsScalarFunction') = 1 begin drop function dbo.F_END_OF_YEAR endgocreate function dbo.F_END_OF_YEAR ( @DAY datetime )returns datetimeas/*Function: F_END_OF_YEAR Finds start of last day of year at 00:00:00.000 for input datetime, @DAY. Valid for all SQL Server datetimes.*/beginreturn dateadd(yy,datediff(yy,-1,@DAY),-1)endgoif objectproperty(object_id('dbo.F_END_OF_QUARTER'),'IsScalarFunction') = 1 begin drop function dbo.F_END_OF_QUARTER endgocreate function dbo.F_END_OF_QUARTER ( @DAY datetime )returns datetimeas/*Function: F_END_OF_QUARTER Finds start of last day of quarter at 00:00:00.000 for input datetime, @DAY. Valid for all SQL Server datetimes.*/beginreturn dateadd(qq,datediff(qq,-1,@DAY),-1)endgoif objectproperty(object_id('dbo.F_END_OF_MONTH'),'IsScalarFunction') = 1 begin drop function dbo.F_END_OF_MONTH endgocreate function dbo.F_END_OF_MONTH ( @DAY datetime )returns datetimeas/*Function: F_END_OF_MONTH Finds start of last day of month at 00:00:00.000 for input datetime, @DAY. Valid for all SQL Server datetimes.*/beginreturn dateadd(mm,datediff(mm,-1,@DAY),-1)endgo/*Start of test scriptLoad dates to test F_END_OF functions*/declare @test_dates table ( DT datetime not null primary key clustered )declare @year varchar(4)select @year = convert(varchar(4),year(getdate()))insert into @test_dates (DT)select DT = getdate() union allselect '17530101 00:00:00.000' union all-- Test start of Decade and Centuryselect '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 '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 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 allselect '89000101 00:00:00.000' union allselect '89991231 23:59:59.997' union allselect '99000101 00:00:00.000' union allselect '99991231 23:59:59.997'order by 1select TYPE = 'CENTURY' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_END_OF_CENTURY( DT ),121)from @test_datesorder by DTselect TYPE = 'DECADE' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_END_OF_DECADE( DT ),121)from @test_datesorder by DTselect TYPE = 'YEAR' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_END_OF_YEAR( DT ),121)from @test_datesorder by DTselect TYPE = 'QUARTER' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_END_OF_QUARTER( DT ),121)from @test_datesorder by DTselect TYPE = 'MONTH' , DT = convert(varchar(23),DT,121), FUNCTION_RESULT = convert(varchar(23),dbo.F_END_OF_MONTH( DT ),121)from @test_datesorder by DT/*End of test script*/
CODO ERGO SUM