Note. . Any answer starting with the expected year can also take a static first date, i.e. replacing @firstMon in my last request below with only the static date "20101227".
SET DATEFIRST 1 declare @targetYear int declare @targetWeek int select @targetYear = 2011, @targetWeek = 23 declare @firstMon datetime set @firstMon = dateadd(d,1-datepart(dw, right(@targetYear,4)+'0101'),right(@targetYear,4)+'0101') select MonOfTargetWeek = dateadd(week, @targetWeek-1, @firstMon), SunOfTargetWeek = dateadd(week, @targetWeek-1, @firstMon+6)
And the real final query that Mon / Sun returns NULL when it doesn't exist this week, like Mon of partial-week-one or Sun of partial-week-53
;with tmp(Mon, Sun) as ( select MonOfTargetWeek = dateadd(week, @targetWeek-1, @firstMon), SunOfTargetWeek = dateadd(week, @targetWeek-1, @firstMon+6) ) select RealMonday = case when Year(Mon) =@targetYear then Mon end, RealSunday = case when Year(Sun) =@targetYear then Sun end from tmp
For GBN they claim that this answer is incorrect (in his answer), below I confirm the correctness
I turned the code into a function.
CREATE function dbo.getMonSunForWeek(@targetYear int, @targetWeek int) returns table as return with pre(firstMon) as ( select dateadd(d,1-datepart(dw, right(@targetYear,4)+'0101'),right(@targetYear,4)+'0101')) , tmp(Mon, Sun) as ( select dateadd(week, @targetWeek-1, firstMon), dateadd(week, @targetWeek-1, firstMon+6) from pre ) select Mon, Sun, RealMonday = case when Year(Mon) =@targetYear then Mon end, RealSunday = case when Year(Sun) =@targetYear then Sun end from tmp GO
And below, I present the ENTIRE range of years and weeks (1-53) for the years from 1950 to 2047. In the case of EVERY ONE , when Monday / Sunday was defined, and works in reverse with DATEPART(week) , SQL Server agrees with the numbering weeks using the function.
set datefirst 1; select [Year] = years.number, [Week] = weeks.number, [Mon] = fun.realmonday, [Sun] = fun.realsunday, [WeekX] = isnull(datepart(week, fun.realmonday), datepart(week, fun.realsunday)), [MonX] = fun.Mon, [SunX] = fun.Sun from master..spt_values years inner join master..spt_values weeks on weeks.type='P' and weeks.number between 1 and 53 cross apply dbo.getMonSunForWeek(years.number, weeks.number) fun where years.type='P' and years.number between 1950 and 2047 order by [year], [Week]
Output information on the transition for 2005-2006
when including prior/next year Year Week Mon-of-week Sun-of-week datepart(week) Mon -and- Sun 2005 52 2005-12-19 2005-12-25 52 2005-12-19 2005-12-25 2005 53 2005-12-26 NULL 53 2005-12-26 2006-01-01 2006 1 NULL 2006-01-01 1 2005-12-26 2006-01-01 2006 2 2006-01-02 2006-01-08 2 2006-01-02 2006-01-08