ISO 8601 Kalenderwoche in Power Query berechnen
This post is also available in: Englisch
Bereits letzte Woche haben wir uns mit der Thematik der korrekten Berechnung der ISO Kalenderwoche in DAX beschäftigt. Da die Frage aufkam, wie man dies in Power Query lösen könnte, werde ich diese Woche darauf eingehen. Für die Problemstellung der Kalenderwochen möchte ich auf den Post von letzter Woche verweisen.
Berechnung der US-Kalenderwoche mit Date.WeekOfYear Funktion
Wie auch in DAX gibt es auch in Power Query bereits eine Funktion zur Berechnung der Kalenderwoche. Diese lautet Date.WeekOfYear und gibt das US-Format mit Wochenstart am Sonntag zurück. Mit optionalem Parameter wird die Kalenderwoche mit Wochenstart an einem Montag zurückgegeben. Die Syntax lautet folgendermaßen:
Date.WeekOfYear(#date(2021, 01, 01), Day.Monday)
Berechnung mit Power Query Funktion
Leider gibt es im Power Query keinen versteckten Parameter wie im DAX, daher müssen wir uns die Kalenderwoche berechnen. Allerdings hat Robert K. Bell bereits die größte Vorarbeit geleistet. Basierend auf seinem Code habe ich die Funktion etwas für unsere Zwecke abgeändert. Den folgenden Code müsst ihr einfach im Power Query in eine neue Query einfügen:
/*
based on https://en.wikipedia.org/wiki/ISO_week_date#Calculating_the_week_number_of_a_given_date
M / Power Query doesn't have a native ISO8601 Week Number function, and DAX's
`weeknum(x, 21)` doesn't give the correct ISO Week-Year.
homepage: https://gist.github.com/r-k-b/18d898e5eed786c9240e3804b167a5ca
*/
let
getISO8601Week = (someDate as date) =>
let
getDayOfWeek = (d as date) =>
let
result = 1 + Date.DayOfWeek(d, Day.Monday)
in
result,
getNaiveWeek = (inDate as date) =>
let
// monday = 1, sunday = 7
weekday = getDayOfWeek(inDate),
weekdayOfJan4th = getDayOfWeek(#date(Date.Year(inDate), 1, 4)),
ordinal = Date.DayOfYear(inDate),
naiveWeek = Number.RoundDown(
(ordinal - weekday + 10) / 7
)
in
naiveWeek,
thisYear = Date.Year(someDate),
priorYear = thisYear - 1,
nwn = getNaiveWeek(someDate),
lastWeekOfPriorYear =
getNaiveWeek(#date(priorYear, 12, 28)),
// http://stackoverflow.com/a/34092382/2014893
lastWeekOfThisYear =
getNaiveWeek(#date(thisYear, 12, 28)),
weekYear =
if
nwn < 1
then
priorYear
else
if
nwn > lastWeekOfThisYear
then
thisYear + 1
else
thisYear,
weekNumber =
if
nwn < 1
then
lastWeekOfPriorYear
else
if
nwn > lastWeekOfThisYear
then
1
else
nwn,
week_dateString =
Text.PadStart(
Text.From(
Number.RoundDown(weekNumber)
),
2,
"0"
)
in
weekNumber
in
getISO8601Week
Danach müsst ihr die Funktion nur noch als neue Spalte mit dem Parameter Datum aufrufen und ihr habt die korrekte Berechnung der Kalenderwoche auch bereits im Power Query:
Die Beispiel-Datei kann hier heruntergeladen werden: