Forum Discussion
DAX elapsed time calculation misbehaving?
Hello all!
I have two seperate, but related questions on some strange results when I use DAX to calcualte elapsed business days from order palcement to order shipment. Both issues occur on both Desktop and Service. I am running the June Desktop update.
Please see the business case for further...
Business case: We are tracking how long a vendor takes to ship our products. One of our DBAs wrote a nice SQL/ M (I’m not sure which) query that gave us a raw calculation that shows time elapsed from order placement to the order being ready for shipment. However, the raw calc doesn’t take into account non-business days. I googled up the below DAX expression to at least filter out weekends. I couldn’t make the same thing for holidays. (Holidays aren’t the reason I’m writing, but if anyone has tips, I’d be happy to experiment…)
Column definitions:
order_initially_placed_at == I sent the order to the vendor for processing (date/time column)
order_received_in_hw == The vendor's system has acknowledged receiving the order (date/time column)
order_last_updated_at == Order has been assigned a tracking # and is awaiting pickup by the shipper (date/time column)
time_elapsed_since_order_placement == the raw elapsed time calculation (last_updated (-) initially placed) (text column)
business_days_elapsed == time elapsed rounded down to the day (whole number column)
Given this DAX calculation:
business_days_elapsed = RoundDown (DateDiff (elapsed_time[order_received_in_hw], elapsed_time[order_last_updated_at], DAY) / 7, 0) * 5 + Mod (5 + Weekday (elapsed_time[order_last_updated_at]) - Weekday (elapsed_time[order_received_in_hw]), 5)
On the table “5 day question” (inside spoiler) why do some of the 5 day lags come out as “0” business days when the rest are correct? (This view is filtered to 5 day lag rows only) Aside from the other question below, the rest of the results are as accurate as they can be considering we’re rounding down to the full day.
| Five Day Question table: | ||||
| order_initially_placed_at | order_received_in_hw | order_last_updated_at | time_elapsed_since_order_placement | business_days_elapsed |
| 06/12/2023 13:39 | 06/12/2023 14:09 | 06/17/2023 23:18 | 5 days 09:09:00.288306 | 0 |
| 06/12/2023 13:39 | 06/12/2023 14:10 | 06/17/2023 23:18 | 5 days 09:08:43.012553 | 0 |
| 06/12/2023 13:40 | 06/12/2023 14:10 | 06/17/2023 23:18 | 5 days 09:08:31.755738 | 0 |
| 06/12/2023 13:40 | 06/12/2023 14:10 | 06/17/2023 23:18 | 5 days 09:08:26.484277 | 0 |
| 06/12/2023 13:43 | 06/12/2023 14:13 | 06/17/2023 23:18 | 5 days 09:05:33.278015 | 0 |
| 06/12/2023 13:43 | 06/12/2023 14:13 | 06/17/2023 23:18 | 5 days 09:05:22.502363 | 0 |
| 06/12/2023 14:10 | 06/12/2023 14:40 | 06/17/2023 23:18 | 5 days 08:38:38.731142 | 0 |
| 06/12/2023 17:50 | 06/12/2023 18:20 | 06/17/2023 23:18 | 5 days 04:58:19.204503 | 0 |
| 06/12/2023 17:50 | 06/12/2023 18:20 | 06/17/2023 23:19 | 5 days 04:58:20.501187 | 0 |
| 06/02/2023 15:01 | 06/02/2023 15:31 | 06/07/2023 17:45 | 5 days 02:13:38.801361 | 3 |
| 06/09/2023 16:05 | 06/09/2023 16:35 | 06/14/2023 22:30 | 5 days 05:54:35.917597 | 3 |
| 06/09/2023 16:12 | 06/09/2023 16:42 | 06/14/2023 22:30 | 5 days 05:47:50.058966 | 3 |
| 06/09/2023 16:12 | 06/09/2023 16:42 | 06/14/2023 22:30 | 5 days 05:47:31.606608 | 3 |
| 06/09/2023 16:12 | 06/09/2023 16:42 | 06/14/2023 22:30 | 5 days 05:47:31.593011 | 3 |
| 06/14/2023 14:07 | 06/14/2023 14:37 | 06/19/2023 22:01 | 5 days 07:23:57.21562 | 3 |
| 06/14/2023 14:07 | 06/14/2023 14:37 | 06/19/2023 22:01 | 5 days 07:23:58.571858 | 3 |
| 06/14/2023 14:08 | 06/14/2023 14:38 | 06/19/2023 22:01 | 5 days 07:23:01.950691 | 3 |
| 06/14/2023 14:08 | 06/14/2023 14:38 | 06/19/2023 22:01 | 5 days 07:23:03.375806 | 3 |
| 06/14/2023 17:25 | 06/14/2023 17:55 | 06/19/2023 22:01 | 5 days 04:05:40.752509 | 3 |
| 06/14/2023 17:25 | 06/14/2023 17:55 | 06/19/2023 22:01 | 5 days 04:05:42.235972 | 3 |
| 06/14/2023 17:25 | 06/14/2023 17:55 | 06/19/2023 22:01 | 5 days 04:05:43.65581 | 3 |
| 06/09/2023 17:44 | 06/09/2023 18:14 | 06/15/2023 15:30 | 5 days 21:15:19.548666 | 4 |
| 06/09/2023 17:50 | 06/09/2023 18:20 | 06/15/2023 15:30 | 5 days 21:10:11.352812 | 4 |
| 06/14/2023 14:06 | 06/14/2023 14:36 | 06/20/2023 13:17 | 5 days 22:40:44.807981 | 4 |
| 06/14/2023 14:06 | 06/14/2023 14:36 | 06/20/2023 13:17 | 5 days 22:40:46.128932 | 4 |
|
A separate but related question: Using the same DAX calculation above, if one of the columns is “null”, why doesn’t the result always show as “0” on the report? The image below is a sample from the same table on Power Query. On the report (inside spoiler below the image), a couple do show “0”, but the rest… well, I have no idea where PBI is coming up with those results.
Correct null results showing in Power Query
| order_initially_placed_at | order_received_in_hw | order_last_updated_at | time_elapsed_since_order_placement | business_days_elapsed |
| 06/08/2023 14:35 | 06/08/2023 15:05 | 0 | ||
| 06/09/2023 16:02 | 06/09/2023 16:32 | 4 | ||
| 06/09/2023 16:02 | 06/09/2023 16:32 | 4 | ||
| 06/09/2023 16:02 | 06/09/2023 16:32 | 4 | ||
| 06/09/2023 16:02 | 06/09/2023 16:32 | 4 | ||
| 06/09/2023 16:02 | 06/09/2023 16:32 | 4 | ||
| 06/09/2023 16:03 | 06/09/2023 16:33 | 4 | ||
| 06/09/2023 16:13 | 06/09/2023 16:44 | 4 | ||
| 06/09/2023 16:14 | 06/09/2023 16:44 | 4 | ||
| 06/09/2023 17:22 | 06/09/2023 17:52 | 4 | ||
| 06/09/2023 17:25 | 06/09/2023 17:55 | 4 | ||
| 06/09/2023 17:32 | 06/09/2023 18:02 | 4 | ||
| 06/09/2023 17:36 | 06/09/2023 18:06 | 4 | ||
| 06/09/2023 17:42 | 06/09/2023 18:12 | 4 | ||
| 06/09/2023 17:46 | 06/09/2023 18:16 | 4 | ||
| 06/09/2023 17:51 | 06/09/2023 18:21 | 4 | ||
| 06/09/2023 17:54 | 06/09/2023 18:24 | 4 | ||
| 06/09/2023 17:57 | 06/09/2023 18:27 | 4 | ||
| 06/09/2023 17:59 | 06/09/2023 18:30 | 4 | ||
| 06/09/2023 18:06 | 06/09/2023 18:36 | 4 | ||
| 06/12/2023 16:18 | 06/12/2023 16:48 | 3 | ||
| 06/12/2023 16:34 | 06/12/2023 17:04 | 3 | ||
| 06/12/2023 16:35 | 06/12/2023 17:05 | 3 | ||
| 06/12/2023 16:39 | 06/12/2023 17:09 | 3 | ||
| 06/12/2023 16:44 | 06/12/2023 17:14 | 3 | ||
| 06/12/2023 16:50 | 06/12/2023 17:20 | 3 | ||
| 06/12/2023 16:58 | 06/12/2023 17:28 | 3 | ||
| 06/13/2023 13:39 | 06/13/2023 14:09 | 2 | ||
| 06/13/2023 13:39 | 06/13/2023 14:09 | 2 | ||
| 06/13/2023 17:15 | 06/13/2023 17:45 | 2 | ||
| 06/13/2023 17:27 | 06/13/2023 17:57 | 2 | ||
| 06/14/2023 17:17 | 06/14/2023 17:47 | 1 | ||
| 06/14/2023 17:30 | 06/14/2023 18:00 | 1 | ||
| 06/15/2023 14:44 | 06/15/2023 15:14 | 0 |
Right now, I use conditional formatting on the column to make the text white so it is kinda hidden when the “last_updated_at” column is null. I’d love for the cells to be blank or “0” (or even “N/A”) when one of the columns in the calculation is null, but I’d settle for just understanding why PBI is behaving like this.
Any thoughts on either question would be appreciated!
I think you can just use the NETWORKDAYS function, e.g.
business_days_elapsed = IF ( NOT ( ISBLANK ( elapsed_time[order_received_in_hw] ) ) && NOT ( ISBLANK ( elapsed_time[order_last_updated_at] ) ), NETWORKDAYS ( elapsed_time[order_received_in_hw], elapsed_time[order_last_updated_at] ) )You can also provide to the NETWORKDAYS function a list of dates to consider as holidays.
5 Replies
- johnt75
Super User
I think you can just use the NETWORKDAYS function, e.g.
business_days_elapsed = IF ( NOT ( ISBLANK ( elapsed_time[order_received_in_hw] ) ) && NOT ( ISBLANK ( elapsed_time[order_last_updated_at] ) ), NETWORKDAYS ( elapsed_time[order_received_in_hw], elapsed_time[order_last_updated_at] ) )You can also provide to the NETWORKDAYS function a list of dates to consider as holidays.
- P_Crane31Frequent Visitor
Thank you johnt75 That's super helpful. I'll need to do some research on how to implement it fully.
I'm trying to learn how to read/ write DAX (I've been using point 'n click so far). Am I reading that expression correctly:
"If elapsed_time[order_received_in_hw] is not blank AND elapsed_time[order_last_updated_at] is not blank, THEN do the Networkdays function"Thanks again!
- johnt75
Super User
Yes, that's exactly right.
- P_Crane31Frequent Visitor
Oops... I just found the DAX formatter...
business_days_elapsed = ROUNDDOWN ( DATEDIFF ( elapsed_time[order_received_in_hw], elapsed_time[order_last_updated_at], DAY ) / 7, 0 ) * 5 + MOD ( 5 + WEEKDAY ( elapsed_time[order_last_updated_at] ) - WEEKDAY ( elapsed_time[order_received_in_hw] ), 5 )