Summary
EventEditorViewModel's default end time can wrap past midnight while EndDate stays on the start date, producing an end instant before the start. Any "New Event" created after roughly 11:30 PM local time builds an invalid default range, and TryBuildEvent fails. It also makes four calendar/event unit tests fail deterministically when the suite runs late in the evening (they construct the VM from DateTime.Now).
Root cause
QuickMail/ViewModels/EventEditorViewModel.cs, the DateTime defaultStart constructor:
var start = RoundUpToQuarterHour(defaultStart);
StartDate = start.Date;
StartTime = start.ToString("t");
EndDate = start.Date; // <-- start's date
EndTime = start.AddMinutes(30).ToString("t"); // <-- can roll to the next day
At 23:38, start rounds up to 23:45. EndTime = 23:45 + 30min = 00:15, formatted time-only as "12:15 AM", but EndDate is still today. When TryBuildEvent recombines EndDate + EndTime, the end lands at today 00:15, which is before the start (today 23:45), so:
if (end < start) { error = ...; return false; } // ~line 327
TryBuildEvent returns false.
Repro
Run any time from ~23:30–23:59 local:
dotnet test QuickMail.Tests/QuickMail.Tests.csproj -c Release --filter "FullyQualifiedName~EventEditorViewModelTests.Repeat_None_ProducesNoRecurrence"
Fails with Assert.True(vm.TryBuildEvent(...)) → Actual: False. The same four tests pass at other times of day:
EventEditorViewModelTests.Repeat_None_ProducesNoRecurrence
EventEditorViewModelTests.Save_RaisesSavedWithBuiltEvent
CalendarViewModelTests.NewEvent_RaisesEditorRequested_AndSavePersistsToService
CalendarViewModelTests.NewEvent_ICloudAccount_OffersOneTargetPerCalendar_PlusLocal
Impact
- Users: creating a new event after ~11:30 PM starts with end-before-start and won't save until the end date/time is corrected.
- CI/tests: four tests fail deterministically on any run in that window (they seed from
DateTime.Now).
Suggested fix
Derive EndDate from the actual end instant so it follows a midnight roll-over:
var end = start.AddMinutes(30);
EndDate = end.Date;
EndTime = end.ToString("t");
Separately, the four tests would be more robust seeded from a fixed DateTime rather than DateTime.Now.
Found while merging main into the server-rules branch (#333/#367); unrelated to that work — the calendar code is untouched there.
Summary
EventEditorViewModel's default end time can wrap past midnight whileEndDatestays on the start date, producing an end instant before the start. Any "New Event" created after roughly 11:30 PM local time builds an invalid default range, andTryBuildEventfails. It also makes four calendar/event unit tests fail deterministically when the suite runs late in the evening (they construct the VM fromDateTime.Now).Root cause
QuickMail/ViewModels/EventEditorViewModel.cs, theDateTime defaultStartconstructor:At 23:38,
startrounds up to 23:45.EndTime=23:45 + 30min= 00:15, formatted time-only as "12:15 AM", butEndDateis still today. WhenTryBuildEventrecombinesEndDate+EndTime, the end lands at today 00:15, which is before the start (today 23:45), so:TryBuildEventreturnsfalse.Repro
Run any time from ~23:30–23:59 local:
Fails with
Assert.True(vm.TryBuildEvent(...))→Actual: False. The same four tests pass at other times of day:EventEditorViewModelTests.Repeat_None_ProducesNoRecurrenceEventEditorViewModelTests.Save_RaisesSavedWithBuiltEventCalendarViewModelTests.NewEvent_RaisesEditorRequested_AndSavePersistsToServiceCalendarViewModelTests.NewEvent_ICloudAccount_OffersOneTargetPerCalendar_PlusLocalImpact
DateTime.Now).Suggested fix
Derive
EndDatefrom the actual end instant so it follows a midnight roll-over:Separately, the four tests would be more robust seeded from a fixed
DateTimerather thanDateTime.Now.Found while merging main into the server-rules branch (#333/#367); unrelated to that work — the calendar code is untouched there.