Forum Discussion
Date / Time difference excluding weekends and factoring working hours
- 1 year ago
so complicated...
(from, to, optional st, optional et) => [s_time = st ?? #time(8, 0, 0), e_time = et ?? #time(17, 0, 0), start = List.Min({from, to}), end = List.Max({from, to}), start_date = Date.From(start), end_date = Date.From(end), gen = List.Generate( () => [c = start_date, sod = List.Max({start, start_date & s_time}), eod = List.Min({end, c & e_time})], (x) => x[c] <= end_date, (x) => [c = Date.AddDays(x[c], 1), sod = c & s_time, eod = List.Min({end, c & e_time})], (x) => if Date.DayOfWeek(x[c], Day.Monday) > 4 then null else x[eod] - x[sod] ), result = if List.NonNullCount({from, to}) < 2 then null else List.Sum(gen)][result]
You'll find a sample below
| début | dateEC | DiffEC | dateT | dateF |
| 19/09/2022 08:00:00 | 19/09/2022 14:09:12 | 0.06:09:12 | 20/01/2023 17:01:57 | 19/09/2022 14:09:57 |
| 03/09/2024 08:00:00 | 17/09/2024 08:09:37 | 3.18:09:37 | null | 17/09/2024 08:09:09 |
| 12/09/2024 08:00:00 | 12/09/2024 14:09:35 | 0.06:09:35 | null | 12/09/2024 16:09:05 |
| 06/09/2024 08:00:00 | 06/09/2024 11:09:53 | 0.03:09:53 | 06/09/2024 14:09:45 | 06/09/2024 14:09:29 |
| 19/09/2022 08:00:00 | 13/10/2022 10:10:09 | 6.20:10:09 | 03/08/2023 15:08:12 | 03/08/2023 15:08:12 |
| 06/09/2024 08:00:00 | 06/09/2024 10:09:45 | 0.02:09:45 | 10/09/2024 11:09:31 | 10/09/2024 11:09:59 |
| 19/09/2022 08:00:00 | null | null | 20/09/2022 09:09:18 | 20/09/2022 09:09:18 |
| 19/09/2022 08:00:00 | null | null | null | 23/09/2022 09:09:17 |
| 09/09/2024 08:00:00 | 09/09/2024 08:09:09 | 0.00:09:09 | 09/09/2024 15:09:37 | 09/09/2024 15:09:16 |
| 19/09/2022 08:00:00 | 19/09/2022 15:09:19 | 0.07:09:19 | 19/09/2022 15:09:11 | 19/09/2022 15:09:01 |
| 09/09/2024 08:00:00 | 09/09/2024 09:09:37 | 0.01:09:37 | 09/09/2024 15:09:14 | 09/09/2024 15:09:55 |
| null | null | null | 02/09/2024 20:09:54 | 02/09/2024 20:09:54 |
| 19/09/2022 08:00:00 | 19/09/2022 14:09:44 | 0.06:09:44 | 16/02/2023 15:02:04 | 20/09/2022 10:09:00 |
| 09/09/2024 08:00:00 | 09/09/2024 09:09:42 | 0.01:09:42 | 09/09/2024 15:09:44 | 09/09/2024 15:09:31 |
| 09/09/2024 08:00:00 | 09/09/2024 09:09:05 | 0.01:09:05 | 09/09/2024 15:09:56 | 09/09/2024 15:09:42 |
| 20/09/2022 08:00:00 | 20/09/2022 15:09:30 | 0.07:09:30 | 20/09/2022 17:09:34 | 20/09/2022 17:09:52 |
| 21/09/2022 08:00:00 | null | null | 29/11/2022 09:11:03 | 29/11/2022 09:11:55 |
| 21/09/2022 08:00:00 | 27/09/2022 15:09:54 | 1.19:09:54 | 28/09/2022 10:09:01 | null |
| 11/09/2024 08:00:00 | 11/09/2024 16:09:48 | 0.08:09:48 | 11/09/2024 17:09:08 | 11/09/2024 17:09:53 |
| 03/09/2024 08:00:00 | null | null | null | 03/09/2024 09:09:22 |
| 11/09/2024 08:00:00 | 11/09/2024 16:09:51 | 0.08:09:51 | 11/09/2024 17:09:39 | 11/09/2024 17:09:31 |
| 21/09/2022 08:00:00 | 21/09/2022 15:09:20 | 0.07:09:20 | 22/11/2022 16:11:55 | 29/09/2022 18:09:00 |
| 03/09/2024 08:00:00 | null | null | null | 03/09/2024 10:09:22 |
| 11/09/2024 08:00:00 | 11/09/2024 17:09:43 | 0.09:00:00 | 12/09/2024 10:09:12 | 12/09/2024 10:09:56 |
| 11/09/2024 08:00:00 | 11/09/2024 17:09:47 | 0.09:00:00 | 12/09/2024 10:09:04 | 12/09/2024 10:09:51 |
| 21/09/2022 08:00:00 | 21/09/2022 17:09:43 | 0.09:00:00 | 21/09/2022 17:09:37 | 21/09/2022 17:09:30 |
| 11/09/2024 08:00:00 | 11/09/2024 17:09:21 | 0.09:00:00 | 12/09/2024 11:09:30 | 12/09/2024 11:09:22 |
| 11/09/2024 08:00:00 | 11/09/2024 17:09:29 | 0.09:00:00 | 12/09/2024 11:09:01 | 12/09/2024 11:09:53 |
| 21/09/2022 08:00:00 | null | null | 21/09/2022 18:09:53 | 21/09/2022 18:09:43 |
I try to get three fieds :
* diff between début and dateEC
* diff between début and dateT
* diff between début and dateF
excluding weekends
Thx for your help
Difference in days?
- Heremion1 year agoFrequent Visitor
Difference in time. After I can convert in days if I have to.
Examples :
18/09/2024 08:00:00 -> 18/09/2024 10:00:00 = 02:00:00
18/09/2024 08:00:00 -> 19/09/2024 10:00:00 = 11:00:00 according working between 08:00:00 and 17:00:00 each day (so 08:00:00 -> 17:00:00 + 08:00:00 -> 10:00:00)
- dufoq31 year agoCommunity Champion
Check this. Ignore first 4 rows (I've added them just for test purpose).
You can edit shiftStart and shiftEnd in Helper step.
EDIT: I've added option where you can decide whether you want to include or exclude weekends:Output
let Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("nVZRbuwwCLxKtd+rLGA7iX2Vam9Q9e/d/zng2NQmaVJppRUTDMMATj4/H7i+IL4IiD5gTgESwOP5IKgorskXtPzez3wsmsfcjWPxT8cQkisOGqWKHmRb89PxmE+ZBlJGYcp17MZWPm4u7gOXBJjCYh3M6JYGdvr+R5rlBxqT22K4CZvx/e/ry/KEKPTJjNtQYeGCos/GHld58kMIwne24ioUkatzEtc1Y+5S+2ChFM/Udy+E2sr8y8U+H/NEzdj0XIv6IeWz0iADvVYNNKoTUDUQuoIdWmg4q6YoXf7U1nAXE64H6NWIe2DXhyiTF83a4zhPXDs0o7lsYpZ5HFCcL+6ReJc0SzVGF7RQwIvVxEZ1Ajzh7S00yPibCkPbFWKZgj9Ab1ws3qvNZAPzWFIb4jyMvrttpUdwRxBPShAx+tK9KYi7pTsElUaMQeHZTC6LqvegpdG1CylQU+R6F0F70RgNJQ1eWNT4Qqz7tO25s9AyMHZEWjriPDE4YawGrX1fcefAU4SW7gqVW9uvIshaDe3CpYOJ5jv7+PVkb4Hrek50h2lAxZSNgZOLJopnQmMnNOkJYYOodi4zkc5xP9VnhVqrPwkiHbwsCJPz5RUazbc31O+NAQ3zrTTLr2n4nhnTXNX9oJrBha/jEYU71RCeVYP1WhjQe72h+GsaXtcBLWt16Z7BbgL5M2pAs7Dv938=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [début = _t, dateEC = _t, DiffEC = _t, dateT = _t, dateF = _t]), ChangedType = Table.TransformColumnTypes(Source,{{"dateF", type datetime}, {"dateT", type datetime}, {"DiffEC", type duration}, {"dateEC", type datetime}, {"début", type datetime}}), Helper = [ shiftStart = #time(8,0,0), shiftEnd = #time(17,0,0), includeWeekends = "no", //type "yes" if you want to include weekends. Type "no" if you want to exclude weekends workingHours = shiftEnd - shiftStart ], fn_WorkingDuration = (previousStep as table, start as text, end as text, optional colName as text)=> let // Ad_StartColumn = Table.DuplicateColumn(ChangedType, "début", "S"), // Ad_EndColumn = Table.DuplicateColumn(Ad_StartColumn, "dateEC", "E"), Ad_StartColumn = Table.DuplicateColumn(previousStep, start, "S"), Ad_EndColumn = Table.DuplicateColumn(Ad_StartColumn, end, "E"), Ad_SDate = Table.AddColumn(Ad_EndColumn, "S Date", each DateTime.Date([S]), type date), Ad_STime = Table.AddColumn(Ad_SDate, "S Time", each DateTime.Time([S]), type time), Ad_EDate = Table.AddColumn(Ad_STime, "E Date", each DateTime.Date([E]), type date), Ad_ETime = Table.AddColumn(Ad_EDate, "E Time", each DateTime.Time([E]), type time), // Weekends excluded Ad_WorkingDays = Table.AddColumn(Ad_ETime, "Working Days", each try [ a = List.Dates([S Date], Duration.TotalDays([E Date] - [S Date]) +1, #duration(1,0,0,0)), //weekends included b = List.Select(a, (x)=> Date.DayOfWeek(x, Day.Monday) < 5), //weekends excluded c = if Text.Trim(Text.Lower(Helper[includeWeekends])) = "yes" then a else b ][c] otherwise null, type list), // [S Date] and [E Date] excluded Ad_FullDaysHours = Table.AddColumn(Ad_WorkingDays, "Full Days Hours", each try [ a = List.RemoveItems([Working Days], { [S Date], [E Date]}), b = Helper[workingHours] * List.Count(a) ][b] otherwise null, type duration), Ad_FirstDayHours = Table.AddColumn(Ad_FullDaysHours, "Fist Day Hours", each try if [S Date] = List.First([Working Days]) then (if [S Date] = [E Date] then List.Min({ [E Time], Helper[shiftEnd] }) else Helper[shiftEnd]) - List.Max({ [S Time], Helper[shiftStart] }) else #duration(0,0,0,0) otherwise null, type duration), Ad_LastDayHours = Table.AddColumn(Ad_FirstDayHours, "Last Day Hours", each try if [S Date] = [E Date] then #duration(0,0,0,0) else if [E Date] = List.Last([Working Days]) then Helper[workingHours] else #duration(0,0,0,0) otherwise null, type duration), // Ad_TotalWorkingDuration = Table.AddColumn(Ad_LastDayHours, "Total Working Duration", each [Full Days Hours] + [Fist Day Hours] + [Last Day Hours], type duration), Ad_TotalWorkingDuration = Table.AddColumn(Ad_LastDayHours, if colName <> null then colName else "Total Working Duration" , each [Full Days Hours] + [Fist Day Hours] + [Last Day Hours], type duration), _RemovedColumns = Table.RemoveColumns(Ad_TotalWorkingDuration,{"S", "E", "S Date", "S Time", "E Date", "E Time", "Working Days", "Full Days Hours", "Fist Day Hours", "Last Day Hours"}) in _RemovedColumns, StepBack = ChangedType, Ad_dateECDuration = fn_WorkingDuration(StepBack, "début", "dateEC", "dateEC duration"), Ad_dateTDuration = fn_WorkingDuration(Ad_dateECDuration, "début", "dateT", "dateT duration"), Ad_dateFDuration = fn_WorkingDuration(Ad_dateTDuration, "début", "dateF", "dateF duration") in Ad_dateFDuration- Heremion1 year agoFrequent Visitor
Hello, Thanks for your help and time.
If I want to make this diff between two of my datetime field, where do I have to put them because I see start and end but they're text field, not datetime field.
Thanks