Datum in ISO Kalenderwoche (1)
Im Bereich der Waren-, Lagerwirtschaft und Disposition arbeitet man in der Regel eher mit der Kalenderwoche statt mit einem fixen Datum; natürlich bevorzugt im der Kalenderwoche nach ISO Norm.
Bis einschließlich dem Microsoft SQL Server 2005 gab es kein Bordmittel zum Umrechnen in die ISO-KW, man fand aber in der BOL unter dem Thema „CREATE FUNCTION (Transact-SQL)“ im Beispiel A. ein Script für eine benutzerdefinierte Funktion „ISOWeek“, mit der man umrechnen kann.
Im MS SQL Server 2008 hat die ISO Woche nun auch im Standard Einzug gehalten mit dem Parameter ISO_WEEK / ISOWK / ISOWW für die Funktion DATEPART:
SELECT DATEPART(ISOWK,
CAST('20060101' AS datetime)) AS IsoWeek
Was mich aber an den Funktionen stört, ist das das Jahr nicht mitgeliefert bzw. das ich bei dem Beispiel mit dem 2006-01-01 darauf achten muss, das die resultierende KW 52 ins Jahr 2005 fällt, nicht in 2006.
Ich habe mir deshalb auf Basis der ISOWeek Funktion eine eigene erstellt, die es mir im Format YYYYWW als Integer zurückliefert. Das auf splitten in ein separates Jahr / Woche ist dann leicht.
SELECT dbo.fnDate2ISOYearWeek(GetDate()) / 100 AS Jahr,
dbo.fnDate2ISOYearWeek(GetDate()) % 100 AS Woche
Hier das Anlage-Script für die Funktion fnDate2ISOYearWeek
-- Alte Version ggf. DROPen
IF OBJECT_ID (N'dbo.fnDate2ISOYearWeek', N'FN') IS NOT NULL
DROP FUNCTION dbo.fnDate2ISOYearWeek;
GO
CREATE FUNCTION dbo.fnDate2ISOYearWeek(@Date datetime)
RETURNS int
AS
-- fnDate2ISOYearWeek - Stand 23.03.2009
-- Liefert zu einem Datum die Kalenderwoche und -Jahr
-- nach ISO im Format YYYYWW als Integer
BEGIN
DECLARE @ISOweek smallint,
@ISOYear int;
SET @ISOYear = DATEPART(yy, @Date);
SET @ISOweek = DATEPART(wk, @DATE) + 1
- DATEPART(wk, CAST(@ISOYear as CHAR(4)) + '0104');
-- Sonderfall: Erste KW <> 4 Tage
IF (@ISOweek = 0)
BEGIN
SET @ISOYear = @ISOYear - 1;
SET @ISOweek = DATEPART(wk, CAST(@ISOYear AS CHAR(4))
+ '12'
+ CAST(24 + DATEPART(DAY, @DATE) AS CHAR(2))
) + 1
- DATEPART(wk, CAST(@ISOYear as CHAR(4)) + '0104')
+ 1;
END;
--Sonderfall: Letzte 3 Tage falen in erste KW Folgejahr
IF DATEPART(mm, @DATE) = 12
AND DATEPART(dd, @DATE) - DATEPART(dw, @DATE) >= 28
BEGIN
SET @ISOweek = 1;
SET @ISOYear = @ISOYear + 1;
END;
RETURN(@ISOYear * 100 + @ISOweek);
END;
GO
-- Unit-Test mit Sonder- und Normalfällen
SELECT Datum, DATENAME(dw, Datum) AS WochenTag,
DATENAME(isowk, Datum) AS InternalIsoWeek,
dbo.ISOweek(Datum) AS MSIsoWeek,
dbo.fnDate2ISOYearWeek(Datum) AS myIsoYearWeek
FROM (SELECT CAST('20060101' as datetime) AS DATUM UNION
SELECT CAST('20060102' as datetime) AS DATUM UNION
SELECT CAST('20061231' as datetime) AS DATUM UNION
SELECT CAST('20050101' as datetime) AS DATUM UNION
SELECT CAST('20050102' as datetime) AS DATUM UNION
SELECT CAST('20050103' as datetime) AS DATUM
) AS DatumsQuelle
ORDER BY DATUM