There is a link here for other earlier attempts http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=60510
This is the OLD code for the function
CREATE function f_isoweek(@date datetime)
RETURNS INT
as
BEGIN
DECLARE @rv int
SELECT @rv = datediff(ww, dateadd(ww, datediff(d, 0, dateadd(yy, datediff(yy, 0, day4),3))/7,-4),day4)
FROM (SELECT dateadd(ww, datediff(day, 0, @date)/7, 3) day4) a
RETURN @rv
END
After combining @AndriyM 's brilliant answer with my own, we are down to 1 line. This is the NEW code.
CREATE function f_isoweek(@date datetime)
RETURNS INT
as
BEGIN
RETURN (datepart(DY, datediff(d, 0, @date) / 7 * 7 + 3)+6) / 7
-- replaced code for yet another improvement.
--RETURN (datepart(DY, dateadd(ww, datediff(d, 0, @date) / 7, 3))+6) / 7
END
Explanation for the old code (not going to explain the new code. It is fragments from my code and AndriyM's code):
Finding weekday 4 of the chosen date
dateadd(week, datediff(day, 0, @date)/7, 3)
Finding isoyear - year of weekday 4 of a week is always the same year as the isoyear of that week
datediff(yy, 0, day4)
When adding 3 days to the first day of the isoyear a random day of the first isoweek of the isoyear is found
dateadd(yy, datediff(yy, 0, day4),3)
finding relative week of the first isoweek of the isoyear
datediff(d, 0, dateadd(yy, datediff(yy, 0, day4),3))/7
Finding the monday minus 4 days of the first isoweek results in thursday of the week BEFORE the first day of the first isoweek of the isoyear
dateadd(ww, datediff(d, 0, dateadd(yy, datediff(yy, 0, day4),3))/7,-4)
Knowing first thursday of the week before the first isoweek
and first thursday of the chosen week,
makes it is quite easy to calculate the week, it doesn't matter which setting datefirst has since the weekdays of both dates are thursdays.
datediff(ww, dateadd(ww, datediff(d, 0, dateadd(yy, datediff(yy, 0, day4),3))/7,-4),day4)