Yep - Stamp the date when it enters the stage and a 'days' to count up business days. On our 'Version 1" of this we logged the change events to a table and did a diff. What we didn't like out of this is if one wants data - someone needs to write some code and it's a 'runtime' result. Before you write code - people need to tell you what they need and why. This can be a moving target.
By capturing this all as hard data on the object - anyone can use if for whatever they need. Below, I've merely added the columns to the project list to demonstrate.
It's real easy to aggregate:
For lifecycle 'stamping' I have an auto-start update process that looks for the stage change event:
...then stamp the appropriate Stage date and, if the days in stage is Null, writes a zero.
Each morning a job runs, evaluates if yesterday was a business day, looks at the stage then adds one to the appropriate days in stage. This gives us true 'business days in stage'.
- If something bounces though multiple stages in a day those will all be zero. This says something.
- If things bounce in and out of stages, we always stamp, effectively being last day it entered the stage. The count doesn't clear. If a request got kicked back to Scoping because the estimates needed redone - this was real elapsed time. The counter counts up from the existing days in stage count - need to see this.
Now that we can see the numbers, we need to put the process engine on our Demand Management process, set SLAs and manage the necessary processes.
Also, the hard numbers makes it easier to use in a process. We do all of this for On Hold projects, and the system sends notifications to the PMs every 30, 60, 90, 120 business days. I can find a number with the process engine's expression editor. I can't diff dates in the expression editor.
HTH