Interestingly enough, I worked through this myself about two months ago:
Here is what I learned:
1) The date a change in status occurs is not stored in any database table or attribute;
2) The only place that change in status is documented is in the Audit attributes of the Note reporting object;
a. Note text is stuff people enter into updates;
b. Audit text is stuff the system documents;
3) To find it, you have to search the notes for a specific set of characters. I’ve tried to create a Note report that show audit (not note) text where:
a. Note>>audit text contains “approved”;
b. Note>>Thread date is greater than equal to $$TODAY-3w (this looks back three weeks);
4) That shows me all notes where the word Approved appears. You can search for other unique strings in the note texts this way. I have a version that shows all projects approved in the last three weeks and another that shows all projects that were moved into or out of another status;
If you want to report on where a project is in an approval workflow, it is a similar challenge. I have some text mode code to help with that.
Hope this helps.