Skip to content
This repository was archived by the owner on Oct 1, 2026. It is now read-only.

Make schedule time-zone behavior explicit - #50

Merged
KalyteraSystems merged 5 commits into
KalyteraSystems:mainfrom
iibaranov-IG:feat/explicit-schedule-time-zone
Sep 30, 2026
Merged

KalyteraSystems merged 5 commits into
KalyteraSystems:mainfrom
iibaranov-IG:feat/explicit-schedule-time-zone

Conversation

@iibaranov-IG

Copy link
Copy Markdown
Contributor

Summary

  • resolve and inject one startup TimeZoneInfo for recurring schedules and UI conversion instead of reading TimeZoneInfo.Local ad hoc
  • use the same TimeProvider for future validation and creation timestamps
  • advance nonexistent spring-forward wall times by the DST gap and choose the earlier UTC occurrence for ambiguous one-time starts
  • keep both repeated-hour instants inside matching recurring windows and retain UTC storage for one-time starts
  • show the active zone and current offset on New session and System check
  • document container TZ defaults and restart/backward-compatibility behavior

Verification

  • dotnet test IPCamLapse.sln -c Release: 111 tests pass (64 IPCamLapse + 47 OpenCamInterop)
  • deterministic custom-zone tests cover spring-forward, fall-back, both repeated-hour instants, overnight windows, and UTC
  • page tests verify the injected zone and offset on both required pages
  • dotnet format IPCamLapse.sln --verify-no-changes --no-restore: pass
  • git diff --check: pass
  • signed commit: 8ab316b

Closes #33.

@elkampu elkampu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The startup dependency/UI direction is sound, but two recurring DST boundaries are incorrect at exact head 3ca4a27. I reproduced both as focused tests against the submitted service:

  1. In the second fall-back hour, Daily 01:30–01:45 at 2026-11-01 06:20Z (01:20 standard time) returns NextStartUtc 05:30Z, which is already in the past. ConvertWallTimeToUtc always chooses the earlier ambiguous occurrence, which is correct for a one-time start but not for the next recurring start after that occurrence has passed.

  2. On spring-forward day, Daily 02:30–04:00 at 07:10Z (03:10 daylight time) reports Active=true. The required gap rule moves the nonexistent 02:30 start to 03:30, so this window must remain inactive until 07:30Z. Raw TimeOfDay membership disagrees with the conversion policy.

Please make recurring boundary evaluation transition-aware for both Daily and Weekly schedules, guarantee a returned NextStartUtc is in the future, and add these focused fall-back/spring-forward regressions. The temporary tests were removed after reproduction.

@iibaranov-IG

iibaranov-IG commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks for reproducing both boundaries so precisely — agreed. DST has once again demonstrated that clocks are hostile distributed systems. I’ll make Daily and Weekly boundary evaluation transition-aware, guarantee that NextStartUtc is actually in the future, apply the gap policy consistently to active-window evaluation, and add focused fall-back and spring-forward regressions.

@iibaranov-IG

Copy link
Copy Markdown
Contributor Author

Готово: recurring-окна теперь оцениваются как UTC-интервалы, с кандидатами для обоих повторов ambiguous wall time. Поэтому второй осенний 01:30 получает собственный будущий старт, а spring-forward 02:30 сдвигается по установленному gap-правилу и не активирует окно раньше времени. Добавил оба воспроизведённых регрессионных сценария. Head: e251297; CI зелёный на Ubuntu, Windows, контейнере и CodeQL. Буду признателен за повторную проверку.

@elkampu elkampu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exact head e251297 fixes the two previously reported boundaries, but another required repeated-hour case still fails. For a daily 00:30–01:15 window, 2026-11-01 06:10Z is the second 01:10 occurrence and must still be active; an exact-head focused regression returns Active=false. In EvaluateRecurring, selecting WallTimeCandidates(endWall).FirstOrDefault(candidate => candidate > startUtc) pairs the unambiguous 00:30 start only with the first 01:15 end (05:15Z) and discards the second valid end (06:15Z). Please model the recurring interval so an ambiguous end includes both repeated-hour instants, add this exact regression for Daily and the equivalent Weekly path, and retain the new spring-gap and second-start coverage.

@iibaranov-IG

Copy link
Copy Markdown
Contributor Author

Addressed the latest review: a window that begins before the repeated fall-back hour now remains active through the second ambiguous end occurrence, while ambiguous starts still pair with their corresponding end. Added Daily and Weekly regressions for the reported 00:30–01:15 case. CI is green on Ubuntu and Windows.

@elkampu elkampu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the revision. The new head fixes the previously reported second 01:10 occurrence, but I reproduced a remaining fall-back boundary regression on this exact head (3b62b36).

For a Daily or Weekly Sunday window of 00:30–01:15 in the test Eastern zone, GetAvailability returns Active = true at 2026-11-01 05:30Z (the first 01:30 local). That is outside the configured wall-clock window. A focused xUnit case for both frequencies fails. EvaluateRecurring chooses the last matching end for the single 00:30 start, forming one continuous 04:30–06:15Z interval; this incorrectly includes the gap between the first 01:15 and second 01:00. The existing 06:10Z second-occurrence test still passes.

Please model the repeated-hour membership without bridging a wall-clock gap, and add Daily and Weekly assertions for both 05:30Z (inactive) and 06:10Z (active) on that date. I am leaving the change request in place until the exact-head behavior is correct.

@KalyteraSystems
KalyteraSystems merged commit 1905a01 into KalyteraSystems:main Sep 30, 2026
5 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make schedule time-zone behavior explicit and deterministic

3 participants