I'm looking for a SQL Server UDF that will be equivalent to DATEPART(WEEK, @date)
, but will allow the caller to specify the first day of the week. Somewhat similar to MySql's WEEK
function. Eg:
CREATE FUNCTION Week (@date date, @firstdayofweek int)
RETURNS int
BEGIN
-- return result would be the same as:
-- SET DATEFIRST @firstdayofweek
-- DATEPART(WEEK, @date)
END
My application does not have the opportunity to call SET DATEFIRST
.
Examples:
SELECT Week('2013-08-28', 2) -- returns 35
SELECT Week('2013-08-28', 3) -- returns 36
The above results would always be the same, regardless of SQL Server's value for @@DATEFIRST
.
You could use something like this:
DATEPART(WEEK, DATEADD(DAY, 8 - @firstdayofweek, @date))
Instead of moving the first day of the week you are moving the actual date. Using this formula the first day of the week would be set using the same number values for days that MS SQL Server uses. (Sunday = 1, Saturday = 7)
I've found a couple of articles that helped me answer to derive an answer to this question:
It may be possible to simplify this UDF, but it gives me exactly what I was looking for:
CREATE FUNCTION Week (@date DATETIME, @dateFirst INT)
RETURNS INT
BEGIN
DECLARE @normalizedWeekOfYear INT = DATEDIFF(WEEK, DATEADD(YEAR, DATEDIFF(YEAR, 0, @date), 0), @date) + 1
DECLARE @jan1DayOfWeek INT = DATEPART(WEEKDAY, DATEADD(YEAR, DATEDIFF(YEAR, 0, @date), 0) + @@DATEFIRST- 7) - 1
DECLARE @dateDayOfWeek INT = DATEPART(WEEKDAY, DATEADD(DAY, @@DATEFIRST- 7, @date)) - 1
RETURN @normalizedWeekOfYear +
CASE
WHEN @jan1DayOfWeek < @dateFirst AND @dateDayOfWeek >= @dateFirst THEN 1
WHEN @jan1DayOfWeek >= @dateFirst AND @dateDayOfWeek < @dateFirst THEN -1
ELSE 0
END
END
GO
Then, executing the following statements would return 35 and 36 respectively:
SELECT dbo.Week('2013-08-28', 2)
SELECT dbo.Week('2013-08-28', 3)
/* No matter how @@DATEFIRST is return result as weekdayName,weekdayNumber Mo 1 Tu 2 Wn 3 Th 4 Fr 5 Sa 6 Su 7 */ CREATE FUNCTION dbo.fnFixWeekday ( @currentDate date ) RETURNS INT AS BEGIN -- get DATEFIRST setting DECLARE @ds int = @@DATEFIRST -- get week day number under current DATEFIRST setting DECLARE @dow int = DATEPART(dw,@currentDate) RETURN 1+(((@dow+@ds) % 7)+5) % 7 END
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.