Forum Discussion
Need help on power query
- 1 year ago
Here is a methodology you may be able to apply to your case.
A brief explanation.
Set a list of holiday names.
Set the working start and end times.
Determine the day of the week of the created datetime. (Using Day.Monday makes Monday day 0)
Compare the created time of the created datetime to the working end time. If the created time is after the working end time then advance the created date by one day.
Now look at the day of the week of the amended created date. If it is Saturday or Sunday then advance the created day to the next Monday. (Call this the effective start date.)
Create a list of dates from the effective start date to and including the close date.
Remove any days from the holiday list from the created date list and then remove any remaining days that are Saturdays or Sundays from the list.
Count the number of rows left in the list and that should be the number of working days.
Hope this gets you pointed in the right direction.let HolidayList = { #date(2025, 3, 30), #date(2025, 3, 31), #date(2025, 4, 1), #date(2025, 4, 2), #date(2025, 6, 5), #date(2025, 6, 8), #date(2025, 6, 9), #date(2025, 6, 10) }, WorkingStart = #time(8, 0, 0), WorkingEnd = #time(17, 0, 0), Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("LcpLCsAwCAXAqxTXAT8vaRKvIt7/Gq3gdpgIErAuNrH1yHUsGjS5QV/HphxBYGiblVXaDeKwTmpt12elX06LOg5lfg==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Created_DateTime = _t, Close_DateTime = _t]), set_types = Table.TransformColumnTypes( Source, {{"Created_DateTime", type datetime}, {"Close_DateTime", type datetime}} ), workingDayCount = Table.AddColumn( set_types, "WorkingDuration", each let dayOfWeek = //Assuming workdays are Monday to Friday, this sets Monday as day 0 Date.DayOfWeek( [Created_DateTime], Day.Monday ), workEndDate = //if the created time is after working hours the created date is advanced to the next day. if Time.From([Created_DateTime]) > WorkingEnd then Date.From(Date.AddDays([Created_DateTime], 1)) else Date.From([Created_DateTime] ), effectiveStartDate = //if the workEndDate is after Friday (day 4 in a zero index list) the date is advanced by the number of days required to get to the next Monday. if dayOfWeek > 4 then Date.AddDays(workEndDate, (7-dayOfWeek)) else workEndDate, initialList = //create a list of dates from the effective start date to and including the clost date. List.Dates( effectiveStartDate, Number.Round(Number.From(Date.From([Close_DateTime]) - effectiveStartDate), 0) + 1, #duration(1,0,0,0) ), dayDuration = //remove the holiday dates and Saturdays and Sundays from the created list and then count the number rows in the list List.Count( List.Select( List.Difference(initialList, HolidayList), each Date.DayOfWeek(_, Day.Monday) <> 5 and Date.DayOfWeek(_, Day.Monday) <> 6 ) ) in dayDuration, type number ) in workingDayCount
A couple of edits:
Instead of skipping to the next working day immediately, include the current day if it's a working day, even if the time is outside working hours. This ensures the current day is still considered in the DateRange.
adjusted =
if dow > 4 or List.Contains(HolidayList, d) then
DateTime.From(nextWorkDate + defaultTime)
else if t < defaultTime then
DateTime.From(d + defaultTime)
else if t >= WorkingEnd then
DateTime.From(d + defaultTime) // Stay on same day, but move to next morning
else
safeDT
In WorkingHours, add a check to ensure WorkingDates is not empty before proceeding:
hours = if List.Count(dates) = 0 then null else List.Sum(
List.Transform(dates, each
let
currentDate = _,
startTime = if currentDate = startDate then Time.From(startDT) else WorkingStart,
endTime = if currentDate = endDate then Time.From(endDT) else WorkingEnd,
validStart = if startTime < WorkingStart then WorkingStart else startTime,
validEnd = if endTime > WorkingEnd then WorkingEnd else endTime,
duration = Duration.TotalHours(validEnd - validStart)
in
if validEnd > validStart then duration else 0
)
)
I hope this helps, please give a thumbs up and mark as solved if it does, thanks!