Why Opsdash Separates Elapsed Calendar Time From Planned Time
On Monday morning, a calendar may already contain a full week of events. Summing them produces scheduled time. Labeling that sum as work already done would give the dashboard a completely different meaning.
Opsdash separates elapsed calendar hours from future calendar hours in the active period. The distinction belongs in aggregation, because every widget and report using the result needs the same interpretation.
Treat events as intervals
Consider a timed event from 10:00 to 12:00, with the current time at 11:15. Its contribution is 1.25 elapsed hours and 0.75 future hours.
For a selected period, the conceptual calculation is:
elapsed interval = event ā© period ā© time before now
future interval = event ā© period ā© time from now onward
hours = non-negative interval duration / 3600
An event crossing a period boundary needs clipping too. Otherwise a meeting that begins outside the selected week contributes hours that do not belong to that week.
The aggregation service accepts a reference time. Injecting that value makes tests reproducible; relying on the wall clock inside every loop would make boundary cases needlessly fragile.
The user's timezone determines the buckets
The instant separating past from future is one boundary. Assigning hours to a local date is another.
An event spanning midnight can contribute to two day buckets. Its original timezone, the user's display timezone, and the selected period must be handled consistently. Formatting a UTC date into a string and using it as a local-day key can put hours on the wrong day.
Daylight-saving transitions also make local calendar days different from a blanket assumption of 24 elapsed hours. Timed-event duration and an all-day reporting policy should be explicit, separate concepts.
All-day events need a policy
An all-day calendar entry does not necessarily represent 24 hours of work. Opsdash has a configurable all-day-hours interpretation.
That is a reporting assumption, so it needs to remain visible. It should not be hidden in a date parser as though it were a property guaranteed by the event itself.
The same principle applies to overlapping events. Summed event duration can exceed elapsed clock time when appointments overlap. An overlap signal helps explain that result; a large total alone does not prove the person worked that many distinct hours.
Preserve the meaning of old fields
The data model retains total_hours for elapsed hours and exposes future_hours separately. Adding a new number is safer than quietly changing an existing number's meaning for downstream consumers.
Useful tests cover a completed event, a future event, an event crossing now, an event crossing the period boundary, and the same cases for a recurring instance.
Elapsed calendar time remains an estimate based on calendar entries. Splitting it from planned time makes that estimate clearer; it does not turn calendar data into attendance tracking.