ISO Kalenderwoche in ein Datum umrechnen
Nach dem Thema für den MS SQL Server, wie man als T-SQL Script ein Datum in eine Kalenderwoche (1) / (2) umrechnet, kommen wir nun zum umgekehrten Weg. Man hat eine ISO Woche + Jahr und möchte dazu einen Tag aus dieser ermitteln. Voraussetzung ist, dass die Funktion fnDate2ISOYearWeek angelegt ist.
Das Umrechnen ist recht einfach, man ermittelt zu einem Datum eine Referenzwoche aus dem Jahr, und rechnet die Differenz aus gesuchter und der Referenzwoche mal 7 Tage, addiert das aufs Referenzdatum und dann noch den Offset für den gewünschten Wochentag. Sieht dann so aus:
-- Alte Version ggf. DROPen IF OBJECT_ID (N'dbo.fnISOYearWeek2Date', N'FN') IS NOT NULL
DROP FUNCTION dbo.fnISOYearWeek2Date; GO CREATE FUNCTION dbo.fnISOYearWeek2Date
(@ISOYear int,
@ISOWeek smallint, @WeekDay smallint) RETURNS datetime AS -- fnISOYearWeek2Date - Stand 23.03.2009 -- Liefert zu ISO Kalenderwoche und -Jahr -- das Datum des übergebenen Wochentages -- Parameter: -- @WeekDay: 1 = Montag ... 7 = Sonntag -- Voraussetzung: -- dbo.fnDate2ISOYearWeek BEGIN DECLARE @RefDate datetime, @RefISOWeek int, @DiffDay smallint,
@Result datetime -- Validierung der Parameter -- Bei datetime kann Jahr nur zwischen 1753 und 9999 liegen IF @ISOYear BETWEEN 1753 AND 9999 -- Woche kann nur zwischen 1 und 53 liegen AND @ISOWeek BETWEEN 1 AND 53 -- Wochentag kann nur zwischen 1 und 7 liegen AND @WeekDay BETWEEN 1 AND 7 BEGIN --Als Referenzdatum den 01. Feb des ISO Jahres SET @RefDate = CONVERT(datetime, CONVERT(char(4), @ISOYear) + '0201');
SET @RefISOWeek = dbo.fnDate2ISOYearWeek(@RefDate) % 100; SET @DiffDay = 7 * (@ISOWeek - @RefISOWeek) - DATEPART(DW, @RefDate) + @WeekDay; SET @Result = DATEADD(d, @DiffDay, @RefDate); END
ELSE -- Ungültiger Parameter, also kein Ergebnis SET @Result = NULL;
RETURN(@Result); END;
GO -- Unit-Test SELECT ISOJahr, ISOWoche,
dbo.fnISOYearWeek2Date(ISOJahr, IsoWoche, 1) FROM (SELECT 2004 AS IsoJahr, 53 AS IsoWoche UNION
SELECT 2005 AS IsoJahr, 1 AS IsoWoche UNION SELECT 2005 AS IsoJahr, 52 AS IsoWoche UNION SELECT 2006 AS IsoJahr, 1 AS IsoWoche UNION SELECT 2006 AS IsoJahr, 53 AS IsoWoche ) AS Quelle ORDER BY IsoJahr, IsoWoche