Here are some Sql tests based on Simon's answer
DECLARE @basestartdate datetime, @baseenddate datetime SET @basestartdate = CAST('1 April 1753' AS datetime) SET @baseenddate = CAST('31 March 1754' AS datetime) ; WITh TestData as ( SELECT CAST('1 April 2015' AS datetime) input, CAST('1 April 2015' AS datetime) expectedstartdate, CAST('31 March 2016' AS datetime) expectedenddate UNION SELECT CAST('2 April 2015' AS datetime), CAST('1 April 2015' AS datetime), CAST('31 March 2016' AS datetime) UNION SELECT CAST('31 December 2015' AS datetime), CAST('1 April 2015' AS datetime), CAST('31 March 2016' AS datetime) UNION SELECT CAST('1 January 2016' AS datetime), CAST('1 April 2015' AS datetime), CAST('31 March 2016' AS datetime) UNION SELECT CAST('28 February 2016' AS datetime), CAST('1 April 2015' AS datetime), CAST('31 March 2016' AS datetime) UNION SELECT CAST('31 March 2016' AS datetime), CAST('1 April 2015' AS datetime), CAST('31 March 2016' AS datetime) UNION SELECT CAST('1 April 2016' AS datetime), CAST('1 April 2016' AS datetime), CAST('31 March 2017' AS datetime) ), Results AS ( SELECT input, expectedstartdate, DATEADD(MONTH, 12 * (DATEDIFF(MONTH, @basestartdate, input) / 12), @basestartdate) startdate, expectedenddate, DATEADD(MONTH, 12 * (DATEDIFF(MONTH, @basestartdate, input) / 12), @baseenddate) enddate FROM testdata ) SELECT CASE WHEN (expectedstartdate = startdate) THEN 'Pass' ELSE 'Fail' END startdateresult, CASE WHEN (expectedenddate = enddate) THEN 'Pass' ELSE 'Fail' END startdateresult FROM results ORDER BY input
Colin
source share