“Run it at six” is incomplete information for a scheduled job. Six where, and should it stay at six when the clocks change? If the requirement is a local wall-clock time, storing a fixed UTC offset can quietly move the job by an hour for part of the year.
I would record the intended time zone alongside the schedule, then calculate the corresponding UTC instant for each occurrence. PHP’s DateTimeImmutable supports working with time-zone-aware date objects without changing the original object in place. The important part is preserving the meaning of the schedule, rather than just getting a plausible timestamp into a field.
The awkward cases deserve an explicit decision: a local time that occurs twice when the clocks go back, or does not occur when they go forward. For a recurring task, adding a fixed number of seconds to yesterday’s execution is not always equivalent to the next local calendar occurrence. Test the dates around a clock change, not only a random Tuesday in the middle of summer.
Time-zone bugs are annoying because the code can be internally consistent and still violate what somebody asked for. A schedule should be readable as a human promise, with a precise instant behind each run. If that promise is “18:00 in London”, keep London in the data.