Looks good!
Just a side note, because everyone gets this wrong:- remember that past events that happened, happen in a time zone, and at a point in time, identifiable by a UTC timestamp and a TimeZone name, plus current offset combination.
Future, planned events however, are going occur at a particular planned time, but only “have happend” once that time has actually been reached in that time zone. Imagine you plan something for 9am in 6 months time, and then all of a sudden, the government of your country decides to move their clocks forward or back on a different day than usual. If that future event had been planned to occur at a particular time UTC according to your current local time zone, then the acutal offset could have slipped or gain time, once the actual time arrives.
Now - if the planned event has been set to repeat itself exactly N hours or minutes in the future, you will want (in code) to ignore time zone changes that may occur and just count linear time since the last time the event /actually/ occurred. If however the event should occur “once per week at 9am”, your user is probably expecting 9am to mean 9am, whatever the current daylight savings time setting, and the difference between those two 9am slots didn’t need to be a fixed period of time.
Hopefully I have articulated that well enough to be making sense.