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.
jaryszek
Super User
1 year agoNot yet.
v-venuppu
Community Support
1 year agoHi jaryszek ,
Could you please let us know the ETA by when you will be able to test the provided solution? This will help us to know when we can follow up. If you encounter any challenges during implementing the provided solution , please inform us and we’ll be glad to assist.
Thank you.