fix #1963: don't do day-time related math on time stamps
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Wed, 31 Oct 2018 09:54:16 +0000 (10:54 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Wed, 31 Oct 2018 13:56:18 +0000 (14:56 +0100)
commit1457ffefbe2263db4a1439a31327ffb06faa773c
treec2e0c8e769cfcca2cbb7be9d041ed408729966d6
parent8881a282778fe3e26c702b2e595b9df55bcea3ec
fix #1963: don't do day-time related math on time stamps

Since our schedules are usually written in local time, we
cannot actually perform calculations using time stamps as
for instance adding 3600 (1 hour) may yield the exact same
local time as before when translated to the current timezone
during a DST change, or might skip an hour. Thus, 2:30am + 1
hour can be all of 2:30am, 3:30am or 4:30am.

Instead, perform the translation to a "day time" array once,
then search for the scheduled time, and only at the end
translate to a time stamp again. This means adding helpers
to wrap around minutes, hours, days (of month)...

Previously, the following code looped endlessly in
compute_next_event under CEST:
    my $dst_time = timelocal(0, 0, 0, 28, 9, 2018);
    my $t = PVE::CalendarEvent::parse_calendar_event('mon..fri');
    my $next = PVE::CalendarEvent::compute_next_event($t, $dst_time);
Afterwards $next will be '2018-10-29 00:00 CET' as expected.

Of course, a day in which 3am appears twice with a scheduled
event for 3am will cause the event to be scheduled twice
now. Ideally we add the ability to make calendar specs use
UTC (and actually use the $utc parameter we have in
compute_next_event()). systemd.time(7) seems to allow simply
suffixing the spec with the string " UTC" for that purpose,
so we should follow this.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
src/PVE/CalendarEvent.pm