fnc_ISOWeek:
/*
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
Text.From(weekYear) & "-W" & week_dateString & "-" & Text.From(getDayOfWeek(someDate))
in
getISO8601Week
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
Text.From(weekYear) & "-W" & week_dateString & "-" & Text.From(getDayOfWeek(someDate))
in
getISO8601Week
==================
dCalendar:
let
Source = List.Dates,
// Step01 = Source(#date(2019, 1, 1), Duration.Days(DateTime.Date(Date.AddDays(DateTime.FixedLocalNow(),1)) - #date(2019,1,1)), #duration(1, 0, 0, 0)),
Step01 = Source(#date(2016, 1, 1), Duration.Days(DateTime.Date(Date.AddDays(DateTime.FixedLocalNow(),1)) - #date(2016,1,1)), #duration(1, 0, 0, 0)),
Step02 = Table.FromList(Step01, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
Step03 = Table.AddIndexColumn(Step02, "Index", 1, 1),
Step04 = Table.RenameColumns(Step03,{{"Column1", "Date"}}),
Step05 = Table.AddColumn(Step04, "Year", each Date.Year([Date])),
Step06 = Table.AddColumn(Step05, "Month Number", each Number.ToText(Date.Month([Date]),"00")),
Step07 = Table.AddColumn(Step06, "Day", each Number.ToText(Date.Day([Date]),"00")),
Step08 = Table.AddColumn(Step07, "Day Name", each Date.ToText([Date],"ddd")),
Step09 = Table.AddColumn(Step08, "Month Name", each Date.ToText([Date],"MMM")),
Step10 = Table.AddColumn(Step09, "Quarter Number", each Date.QuarterOfYear([Date])),
Step11 = Table.AddColumn(Step10, "Short Year", each Date.Year([Date])),
Step12 = Table.TransformColumnTypes(Step11,{{"Short Year", type text}}),
Step13 = Table.SplitColumn(Step12,"Short Year",Splitter.SplitTextByRepeatedLengths(2),{"Short Year.1", "Short Year.2"}),
Step14 = Table.TransformColumnTypes(Step13,{{"Short Year.1", Int64.Type}, {"Short Year.2", Int64.Type}}),
Step15 = Table.RemoveColumns(Step14,{"Short Year.1"}),
Step16 = Table.RenameColumns(Step15,{{"Short Year.2", "Short Year"}}),
Step17 = Table.AddColumn(Step16, "Quarter Year", each Number.ToText([Short Year]) & "Q" & Number.ToText([Quarter Number],"00")),
Step18 = Table.AddColumn(Step17, "StartWeek", each Date.StartOfWeek([Date])),
Step19 = Table.AddColumn(Step18, "YYYYMM", each Number.ToText(Date.Year([Date])) & Number.ToText(Date.Month([Date]),"00")),
Step20n = Table.AddColumn(Step19, "YYYYWeekYear", each Number.ToText(Date.Year([Date])) & Number.ToText(Date.WeekOfYear([Date], Day.Saturday),"00")),
Step20 = Table.AddColumn(Step20n, "WeekDay", each Number.ToText(Date.DayOfWeek([Date], Day.Saturday),"00")),
Step21 = Table.AddColumn(Step20, "YYYYMMDD", each Number.ToText(Date.Year([Date])) & Number.ToText(Date.Month([Date]),"00") & Number.ToText(Date.Day([Date]),"00")),
Step22 = Table.AddColumn(Step21, "MMDD", each Number.ToText(Date.Month([Date]),"00") & Number.ToText(Date.Day([Date]),"00")),
Step23 = Table.TransformColumnTypes(Step22,{{"Date", type date}, {"Index", Int64.Type}, {"Year", Int64.Type}, {"Month Number", Int64.Type}, {"Day", Int64.Type}, {"Day Name", type text}, {"Month Name", type text}, {"Quarter Number", Int64.Type}, {"Short Year", Int64.Type}, {"Quarter Year", type text}, {"StartWeek", type date}, {"YYYYMM", Int64.Type}, {"WeekDay", Int64.Type}, {"YYYYMMDD", Int64.Type}}),
Step24 = Table.SelectRows(Step23, each true),
Step25 = Table.Sort(Step24,{{"YYYYMMDD", Order.Descending}}),
Step26 = Table.AddColumn(Step25, "WeekName", each Number.ToText([WeekDay]) & " - " & [Day Name]),
Step27 = Table.AddColumn(Step26, "QtdDias", each DateTime.Date(Date.AddDays(DateTime.FixedLocalNow(),1)) - [Date]),
Step28 = Table.AddColumn(Step27, "WeekYear", each Date.WeekOfYear([Date])),
Step29 = Table.TransformColumnTypes(Step28,{{"QtdDias", Int64.Type}, {"Date", type date}, {"Index", Int64.Type}, {"Year", Int64.Type}, {"Month Number", Int64.Type}, {"Day", Int64.Type}, {"Day Name", type text}, {"Month Name", type text}, {"Quarter Number", Int64.Type}, {"Short Year", Int64.Type}, {"Quarter Year", type text}, {"StartWeek", type date}, {"YYYYMM", Int64.Type}, {"WeekDay", Int64.Type}, {"YYYYMMDD", Int64.Type}, {"MMDD", Int64.Type}, {"WeekName", type text}, {"WeekYear", Int64.Type}}),
Step30 = Table.AddColumn(Step29, "Zodiac", each if ([MMDD] >= 0121 and [MMDD] <= 0218) then "Z01" else
if ([MMDD] >= 0219 and [MMDD] <= 0320) then "Z02" else
if ([MMDD] >= 0321 and [MMDD] <= 0420) then "Z03" else
if ([MMDD] >= 0421 and [MMDD] <= 0521) then "Z04" else
if ([MMDD] >= 0522 and [MMDD] <= 0621) then "Z05" else
if ([MMDD] >= 0622 and [MMDD] <= 0722) then "Z06" else
if ([MMDD] >= 0723 and [MMDD] <= 0823) then "Z07" else
if ([MMDD] >= 0824 and [MMDD] <= 0923) then "Z08" else
if ([MMDD] >= 0924 and [MMDD] <= 1023) then "Z09" else
if ([MMDD] >= 1024 and [MMDD] <= 1122) then "Z10" else
if ([MMDD] >= 1123 and [MMDD] <= 1221) then "Z11" else
if ([MMDD] >= 1222 or [MMDD] <= 0120) then "Z12" else "???"),
#"Invoked Custom Function" = Table.AddColumn(Step30, "ISOWeek", each fnc_ISOWeek([Date]))
in
#"Invoked Custom Function"