Repository navigation
Charts and time windows keep exact instants across daylight saving changes, in Lite and the Darling viewer (#4766) - #4848
Merged
Merged
Conversation
… bounds and UTC windows across daylight saving changes (fails until the next commit) (#4766)
…C windows for exact times across daylight saving changes (#4766)
…read, so a range in the repeated hour reads the hour it names (#4766)
…daylight saving changes, and multi-server lists show each server's own time (#4766)
…sen in one place, ViewerTimeHelper, for the Recommendations loader and both lists (#4766)
…ns take UTC inputs (#4766)
… is read as live-store cleanup (#4766)
…r reads the instants it names, and the held range survives a display switch (#4766)
… bounds as UTC instants (#4766)
…air and the CSV export show it in the display zone (#4766)
…adings in the repeated hour stay two points (#4766)
…umn property, so the timestamp-frame census reads it as the conversion it is (#4766)
…how it in the display zone (#4766)
…w each server's time in the display mode, on that server's own clock (#4766)
…ole hours of the display zone (#4766)
…the instant frame, and a time test no longer depends on the machine's zone (#4766) - The alert row time test names its display mode, its server clock and its zone, so it holds on any machine and any date. It failed on a US Eastern machine once the clocks went back, because Server mode ran on a fixed offset read at startup. Its class joins the collection that serializes tests of the process-wide time statics. - The chart CSV export writes each point through a pure line builder. A test pins that a point at 06:30Z on 2026-11-01 reads 01:30 in US Eastern (the second 01:30) and 06:30 in UTC. - The renderer host pin now covers any chart renderer a viewer tab builds, and requires X to pass through untouched (static utc => utc) with the display zone as the last argument. - The alert history read takes the fleet's server clocks from a short-lived cache on the data service instead of sorting the retained server_properties rows on every refresh tick (every 30 seconds by default). A failed read is never held. Pinned without a database. - Docs that described a chart X as ForDisplay(utc) or the display frame now say the instant is plotted and drawn in CurrentDisplayZone, and that ForDisplay is for text only.
…e into a local the label shares (#4766)
… they do in UTC and Local modes (#4766)
…nd the zoneless hover out (#4766) Every chart now plots the UTC instant and words its axis and hover in a display zone, so nothing reads the shared time hook: it is no longer wired at startup.
…ive-UTC instant and the text is drawn in the display zone (#4766)
…lock, and the viewer's chart export names its zone (#4766)
…istory rows' clock arms, the Worded formatters and TimeWindows.GhostX (#4766)
… clock after the zone (#4766)
…ame (#4766) Comment and summary text only; no code line changes. Every chart plots the UTC instant and the display zone applies only to text, so the remaining wording that described the server wall-clock frame now says what the code does: the comparison-range note, the alert-badge window, the drill and round-trip test summaries, the shared-renderer summaries, and the grid-refresh note.
…ery caller passes them (#4766)
… and the drill indicator shows the offset in the repeated hour (#4766) A tab behind the one on screen no longer reloads when Apply to All hands it a range, so it cannot leave its own server's clock on the visible tab's hover and ticks; it reloads when it is selected. The two drills that open Active Queries and the heatmap hover word their times through DisplayZone.Format, like Lite, so the repeated hour of an autumn change carries each end's UTC offset. The DisplayZone remarks on a shift past the ends of the calendar now say what the code does.
…d argument, like the other two tabs (#4766)
erikdarlingdata
marked this pull request as ready for review
September 30, 2026 01:37
This was referenced Sep 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4766.
Why
Lite and the Darling viewer plotted each chart point at the server's wall-clock time. In the repeated autumn hour, two real hours shared one X value and the line ran back on itself. A drill or a typed range there sometimes read the wrong hour or came back empty. In the spring gap, the axis showed an hour that never happened.
Now every chart point sits at its UTC instant. The display mode (Server, Local or UTC) applies only when text is drawn: ticks, hover, the crosshair, labels, grids and the CSV export. Time windows stay UTC from the picker, slicer or drill to the read.
What changes
Rules
Shared parts (new)
ServerClock.AsTimeZone()returns the server's zone, a fixed-offset zone, or UTC.PerformanceMonitor.Ui/DisplayZonewrites a UTC instant in a display zone.ToUtcBoundturns a typed wall time into a UTC bound, andWallTickslists wall-clock ticks.DisplayZoneTickGeneratorputs chart ticks at whole wall times of the display zone. A skipped time gets no tick, and a repeated time gets one tick per occurrence.AxesExtensions.DateTimeTicksBottomUtcsets it on an axis.CustomRangeStateholds a custom range as a UTC pair and applies a typed edit.TimeWindowshasChartAxis,Drill,OverviewReferenceandGhostX. The last two line up on the server's wall clock N days back.ChartHoverHelper,CorrelatedCrosshairManagerand the four shared renderers take a display zone. The renderers areCpuSchedulerChartRenderer,GroupedTrendChartRenderer,SessionStatsChartRendererandSystemHealthChartRenderer.Lite
DateTime (<zone id>).UiTimeContext.ConvertForDisplay, set inApp.xaml.cs),GetCurrentWindowServerLocal, the oldGetTimezoneLabeloverloads,ServerZoneLabelandServerTimeHelper.ToServerTime.Darling viewer
ViewerTimeHelper.DisplayToNaiveUtcandConvertFromDisplayare deleted.Not in this change
Query_HeatmapandMemory_Pressure_Eventschart exports write only the header row, as before. They draw a heatmap and bars, not scatter series.Test plan
TypedBoundTests.RepeatedHour_FromTakesTheFirst_ToTakesTheSecond: expected 06:45Z, got 05:45Z.TypedBoundTests.SkippedHour_BothBoundsTakeTheChangeInstant: expected 07:00Z, got 07:30Z.TypedBoundTests.AnEditInsideTheSecondOccurrence_TakesTheFirstForFrom: expected 05:15Z, got 06:15Z.TimeWindowsTests.ADrillInTheRepeatedHour_OpensSixtyRealMinutes: expected 05:15Z to 06:15Z, got 05:15Z to 07:15Z.SecondOccurrenceReadTests.AWindowOverTheSecondOccurrence_ReturnsOnlyItsRows: expected 06:00, got 11:00.ServerTabDrillWindowTests.AClickInTheRepeatedAutumnHour_OpensSixtyRealMinutes: expected 05:00, got 01:00.WindowedReadServerClockTests.ACustomUtcWindow_ReachesTheReadUnchanged: expected 06:30, got 11:30.ServerTabChartWindowTests.ASpringChangeInsideThePresetWindow_LeavesNoRowLeftOfTheAxis.ViewerChartUtcFrameTests.NoDisplayTimeProjectionFeedsAChartXandNoViewerChartUsesADisplayFrameAxis.OverviewLanesUtcFrameTests.TheOverviewLanes_ConvertNothingThroughTheServersClock.OverviewComparisonWindowOffsetTests.GetOverviewComparisonRange_Yesterday_AcrossSpringForward_IsTheSameWallHoursOnTheServersClock.ServerTimeHelperClockTests.FormatServerTime_InTheRepeatedHour...: expected "2026-11-01 06:30:00", got "05:30:00".ChartCsvExportDisplayZoneTests.ThePointAt0630Z_OnTheAutumnChangeDay_IsWritten0130InEastern_And0630InUtc: expected 01:30:00, got 06:30:00.DisplayZoneTextFrameTests.GetTimeRangeDescription_NamesBothEndsInTheZoneItIsGiven_ThroughTheRepeatedHour.HistoryGridZoneTests.AZone_WordsEveryInstantColumn_InThatZone(rowType: "QueryStoreHistoryRow").HistoryGridZoneTests.TheServerClockColumns_AreConvertedOnTheRowsOwnClock_NotTheSelectedTabs(rowType: "QueryStatsHistoryRow").ViewerDrillDownTests.TheDrillIndicator_InTheRepeatedHour_NamesTheOffsetOfEachEnd_ForBothDrills: expected -04:00 and -05:00, got "01:15 → 01:15".ViewerApplyToAllClockTests.ApplyExternalTimeRange_ReloadsOnlyWhenTheTabIsVisible_AndItsReloadIsTheLastStatement. It is a source pin, because a viewer tab cannot be built in a test. It cannot catch a hidden tab whoseIsVisiblereads true, or another writer of the clock.DisplayZoneTests,DisplayZoneTickTests,TypedBoundTests,CustomRangeStateTests,TimeWindowsTests,ServerClockAsTimeZoneTests,DisplayZoneRendererTests,SecondOccurrenceReadTests,ServerTabHeldRangeTests,ServerTabChartUtcFrameTests,ViewerChartUtcFrameTests,ViewerAlertClockCacheTests,OverviewLanesUtcFrameTests,ChartCsvExportDisplayZoneTests,DisplayZoneTextFrameTests,HistoryGridZoneTestsandViewerApplyToAllClockTests.ServerTabDrillWindowTests,WindowedReadServerClockTestsandViewerDrillDownTestsgain repeated-hour cases. Pins that asserted the old frame now assert the instant.OverviewComparisonWindowOffsetTestsandCorrelatedLanesXAxisWindowTestswere rewritten.CHANGELOG
SECTION: Fixed
ENTRY:
DateTime (UTC), so a script that matches the headerDateTimeneeds the new name.REF:
[Charts and time windows keep exact instants across daylight saving changes, in Lite and the Darling viewer (#4766) #4848]: Charts and time windows keep exact instants across daylight saving changes, in Lite and the Darling viewer (#4766) #4848