Forum Discussion
jaryszek
Super User
1 year agoHow to handle 53th week 445 calendar
Hi Guys, I am try to use this code: https://gorilla.bi/power-query/445-calendar/ let
// ===== USER PARAMETERS =====
StartDate = #date(2024, 1, 29), // Enter your fiscal calenda...
- 1 year ago
pls try
let // ===== USER PARAMETERS ===== StartDate = #date(2024, 1, 29), // Enter your fiscal calendar start date EndDate = #date(2030, 1, 25), // Enter your fiscal calendar end date Order445 = {4, 4, 5}, // Pattern for months in quarter: 4-4-5 // ===== 53RD WEEK LOGIC ===== // Function to determine if a fiscal year needs 53 weeks Needs53Weeks = (fiscalYearStart as date) as logical => let // Method 1: Check if fiscal year start falls on Thursday, Friday, or Saturday startDayOfWeek = Date.DayOfWeek(fiscalYearStart, Day.Monday), // 0=Monday, 6=Sunday needsExtra = startDayOfWeek >= 3 and startDayOfWeek <= 5 // Thu, Fri, Sat in needsExtra, // Alternative method: Check if adding 364 days overshoots the next fiscal year start // This is more accurate for custom fiscal calendars Needs53WeeksAlt = (fiscalYearStart as date, nextFiscalYearStart as date) as logical => let standardYearEnd = Date.AddDays(fiscalYearStart, 363), // 364 days - 1 daysBetween = Duration.Days(nextFiscalYearStart - fiscalYearStart), needsExtra = daysBetween > 364 in needsExtra, // ===== CREATE BASE DATE LIST ===== Dates = List.Dates(StartDate, Duration.Days(EndDate-StartDate)+1, #duration(1,0,0,0)), Source = Table.FromList(Dates, Splitter.SplitByNothing(), {"Date"}), AddDayIndex = Table.AddIndexColumn(Source, "DayIndex", 0, 1, Int64.Type), // ===== FISCAL YEAR CALCULATION WITH 53RD WEEK ===== BaseDaysInYear = List.Sum(Order445) * 4 * 7, // 364 days DaysInQuarter = List.Sum(Order445) * 7, // 91 days // Determine fiscal year boundaries considering 53rd week AddFiscalYearInfo = Table.AddColumn(AddDayIndex, "FiscalYearInfo", (row) => let currentDate = row[Date], yearsSinceStart = Number.IntegerDivide(row[DayIndex], BaseDaysInYear), // Calculate this fiscal year's start baseYearStart = Date.AddDays(StartDate, yearsSinceStart * BaseDaysInYear), // Check if this fiscal year needs 53 weeks needs53 = Needs53Weeks(baseYearStart), actualDaysInYear = if needs53 then BaseDaysInYear + 7 else BaseDaysInYear, // Recalculate year index with variable year lengths adjustedYearIndex = let totalDays = 0, yearIndex = 1, findYear = List.Generate( () => [year = 1, cumulativeDays = 0], each [cumulativeDays] <= row[DayIndex], each let yearStart = Date.AddDays(StartDate, [cumulativeDays]), yearNeeds53 = Needs53Weeks(yearStart), yearDays = if yearNeeds53 then BaseDaysInYear + 7 else BaseDaysInYear in [year = [year] + 1, cumulativeDays = [cumulativeDays] + yearDays] ), lastItem = List.Last(findYear) in lastItem[year] - 1, fiscalYear = Date.Year(StartDate) + adjustedYearIndex - 1 in [ YearIndex = adjustedYearIndex, FiscalYear = fiscalYear, Has53Weeks = needs53, DaysInThisYear = actualDaysInYear ], type record ), // Extract fiscal year info AddYearIndex = Table.AddColumn(AddFiscalYearInfo, "YearIndex", each [FiscalYearInfo][YearIndex], Int64.Type), AddFiscalYear = Table.AddColumn(AddYearIndex, "FiscalYear", each [FiscalYearInfo][FiscalYear], Int64.Type), AddHas53Weeks = Table.AddColumn(AddFiscalYear, "Has53Weeks", each [FiscalYearInfo][Has53Weeks], Logical.Type), AddDaysInYear = Table.AddColumn(AddHas53Weeks, "DaysInThisYear", each [FiscalYearInfo][DaysInThisYear], Int64.Type), // Calculate day of fiscal year (1-364 or 1-371) AddDayOfYear = Table.AddColumn(AddDaysInYear, "DayOfYear", (row) => let // Find the start of this fiscal year yearStartDayIndex = let findStart = List.Generate( () => [year = 1, cumulativeDays = 0], each [year] < row[YearIndex], each let yearStart = Date.AddDays(StartDate, [cumulativeDays]), yearNeeds53 = Needs53Weeks(yearStart), yearDays = if yearNeeds53 then BaseDaysInYear + 7 else BaseDaysInYear in [year = [year] + 1, cumulativeDays = [cumulativeDays] + yearDays] ), result = if List.Count(findStart) = 0 then 0 else List.Last(findStart)[cumulativeDays] in result, dayOfYear = row[DayIndex] - yearStartDayIndex + 1 in dayOfYear, Int64.Type ), // ===== QUARTER AND PERIOD CALCULATION ===== AddQuarterInfo = Table.AddColumn(AddDayOfYear, "QuarterInfo", (row) => let dayOfYear = row[DayOfYear], has53Weeks = row[Has53Weeks], // Standard quarter calculation quarterIndex = Number.IntegerDivide(dayOfYear-1, DaysInQuarter) + 1, dayOfQuarter = Number.Mod(dayOfYear-1, DaysInQuarter) + 1, // Adjust for 53rd week (add to Q4) adjustedQuarter = if has53Weeks and dayOfYear > (DaysInQuarter * 3) then [ QuarterIndex = 4, DayOfQuarter = dayOfYear - (DaysInQuarter * 3), DaysInThisQuarter = DaysInQuarter + 7 // Q4 gets extra week ] else if quarterIndex > 4 then // Safety check [ QuarterIndex = 4, DayOfQuarter = dayOfQuarter + DaysInQuarter, DaysInThisQuarter = DaysInQuarter + 7 ] else [ QuarterIndex = quarterIndex, DayOfQuarter = dayOfQuarter, DaysInThisQuarter = if quarterIndex = 4 and has53Weeks then DaysInQuarter + 7 else DaysInQuarter ] in adjustedQuarter, type record ), AddQuarterIndex = Table.AddColumn(AddQuarterInfo, "QuarterIndex", each [QuarterInfo][QuarterIndex], Int64.Type), AddDayOfQuarter = Table.AddColumn(AddQuarterIndex, "DayOfQuarter", each [QuarterInfo][DayOfQuarter], Int64.Type), AddDaysInQuarter = Table.AddColumn(AddDayOfQuarter, "DaysInThisQuarter", each [QuarterInfo][DaysInThisQuarter], Int64.Type), // ===== PERIOD CALCULATION WITH 53RD WEEK ===== AddPeriodInfo = Table.AddColumn(AddDaysInQuarter, "PeriodInfo", (row) => let dayOfQuarter = row[DayOfQuarter], quarterIndex = row[QuarterIndex], has53Weeks = row[Has53Weeks], order = Order445, // Calculate period within quarter periodOfQuarter = if dayOfQuarter <= order{0} * 7 then 1 else if dayOfQuarter <= (order{0} + order{1}) * 7 then 2 else 3, // For 53rd week: add to last period of last quarter (Period 12) isLastPeriodWith53 = quarterIndex = 4 and periodOfQuarter = 3 and has53Weeks, // Calculate days in this period daysInPeriod = let standardDays = order{periodOfQuarter-1} * 7 in if isLastPeriodWith53 then standardDays + 7 else standardDays, // Calculate day of period dayOfPeriod = let offset = if periodOfQuarter = 1 then 0 else if periodOfQuarter = 2 then order{0} * 7 else (order{0} + order{1}) * 7 in dayOfQuarter - offset, // Period number in fiscal year periodOfYear = (quarterIndex - 1) * 3 + periodOfQuarter in [ PeriodOfQuarter = periodOfQuarter, Period = periodOfYear, DayOfPeriod = dayOfPeriod, DaysInPeriod = daysInPeriod, IsLeapPeriod = isLastPeriodWith53 ], type record ), AddPeriodOfQuarter = Table.AddColumn(AddPeriodInfo, "PeriodOfQuarter", each [PeriodInfo][PeriodOfQuarter], Int64.Type), AddPeriod = Table.AddColumn(AddPeriodOfQuarter, "Period", each [PeriodInfo][Period], Int64.Type), AddDayOfPeriod = Table.AddColumn(AddPeriod, "DayOfPeriod", each [PeriodInfo][DayOfPeriod], Int64.Type), AddDaysInPeriod = Table.AddColumn(AddDayOfPeriod, "DaysInPeriod", each [PeriodInfo][DaysInPeriod], Int64.Type), AddIsLeapPeriod = Table.AddColumn(AddDaysInPeriod, "IsLeapPeriod", each [PeriodInfo][IsLeapPeriod], Logical.Type), // ===== WEEK CALCULATIONS ===== AddWeekIndex = Table.AddColumn(AddIsLeapPeriod, "WeekIndex", each Number.IntegerDivide([DayOfYear]-1, 7) + 1, Int64.Type), AddWeekOfQuarter = Table.AddColumn(AddWeekIndex, "WeekOfQuarter", each Number.Mod([WeekIndex]-1, if [Has53Weeks] and [QuarterIndex] = 4 then 14 else 13) + 1, Int64.Type), AddWeekOfPeriod = Table.AddColumn(AddWeekOfQuarter, "WeekOfPeriod", each Number.IntegerDivide([DayOfPeriod]-1, 7) + 1, Int64.Type), // ===== LABELS ===== AddQuarterLabel = Table.AddColumn(AddWeekOfPeriod, "QuarterLabel", each "Q" & Text.From([QuarterIndex])), AddPeriodLabel = Table.AddColumn(AddQuarterLabel, "PeriodLabel", each "P" & Text.PadStart(Text.From([Period]),2,"0")), AddWeekLabel = Table.AddColumn(AddPeriodLabel, "WeekLabel", each "W" & Text.PadStart(Text.From([WeekIndex]),2,"0")), // ===== DATE RANGES ===== // Week Start and End (assuming weeks start on Monday) AddWeekStart = Table.AddColumn(AddWeekLabel, "WeekStart", each Date.AddDays([Date], -Number.Mod(Date.DayOfWeek([Date], Day.Monday), 7))), AddWeekEnd = Table.AddColumn(AddWeekStart, "WeekEnd", each Date.AddDays([WeekStart], 6)), // Fiscal Year Start and End AddYearStart = Table.AddColumn(AddWeekEnd, "YearStart", each Date.AddDays([Date], -([DayOfYear]-1))), AddYearEnd = Table.AddColumn(AddYearStart, "YearEnd", each Date.AddDays([YearStart], [DaysInThisYear]-1)), // Fiscal Quarter Start and End AddQuarterStart = Table.AddColumn(AddYearEnd, "QuarterStart", each Date.AddDays([Date], -([DayOfQuarter]-1))), AddQuarterEnd = Table.AddColumn(AddQuarterStart, "QuarterEnd", each Date.AddDays([QuarterStart], [DaysInThisQuarter]-1)), // Period Start and End AddPeriodStart = Table.AddColumn(AddQuarterEnd, "PeriodStart", each Date.AddDays([Date], -([DayOfPeriod]-1))), AddPeriodEnd = Table.AddColumn(AddPeriodStart, "PeriodEnd", each Date.AddDays([PeriodStart], [DaysInPeriod]-1)), // Clean up and reorder columns RemoveHelperColumns = Table.RemoveColumns(AddPeriodEnd, {"DayIndex", "FiscalYearInfo", "QuarterInfo", "PeriodInfo"}), FinalTable = Table.SelectColumns( RemoveHelperColumns, { "Date", "FiscalYear", "YearStart", "YearEnd", "Has53Weeks", "DaysInThisYear", "QuarterIndex", "QuarterLabel", "QuarterStart", "QuarterEnd", "DaysInThisQuarter", "Period", "PeriodLabel", "PeriodStart", "PeriodEnd", "DaysInPeriod", "IsLeapPeriod", "WeekIndex", "WeekLabel", "WeekOfQuarter", "WeekOfPeriod", "WeekStart", "WeekEnd", "DayOfYear", "DayOfQuarter", "DayOfPeriod" } ) in FinalTable - 1 year ago
Calendars are immutable. There is no point trying to do this in Power Query or DAX. Use an external precomputed reference table.
v-venuppu
Community Support
1 year agoHi jaryszek ,
May I ask if you have resolved this issue? If so, please mark the helpful reply and accept it as the solution. This will be helpful for other community members who have similar problems to solve it faster.
Thank you.
jaryszek
Super User
1 year agoPlease do not close the topic