Repository navigation
fix(core): compareTo on an already-past date range compares with the period before it, and previousYear from 29 February stays in February - #30246
Merged
Conversation
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.
Requested by Yibo Wang · project thread
Fixes #30197
维护者速读
compare-to.ts一个文件的逻辑,不动规范、不动服务端。「今天」「本周/本月/本季度/今年」和三个前向预设的环比窗口逐字节不变;变化的只有上述后向预设,以及 2 月 29 日那天的去年同期。回滚即 revert。compare-to.ts的lastPeriodBefore(规范没有「前两期」的宏,窗口是算出来的);② 同文件rollingPair的后向分支(N+1 天整体后移);③previousYear的日期夹取。pnpm --dir ui exec vitest run packages/core/src/utils/__tests__/dashboard-filters.presetWindows-29116.test.ts,预期 16 个预设全部通过,每个预设的上一期都在本期开始前一天结束。Clause-②: no
Metadata-protocol: none
What changes
@object-ui/coreshiftFilterByCompareTo,kind: 'previousPeriod'.{yesterday}andlast_week_*/last_month_*/last_quarter_*/last_year_*were never substituted, so theyesterday,last_week,last_month,last_quarterandlast_yearpresets compared the window with itself. Now{yesterday}becomes{2_days_ago}, and eachlast_*token becomes the period before last.DATE_MACRO_TOKENS(packages/spec/src/data/date-macros.zod.ts) stops atlast_*, and the parameterised grammar ({N_weeks_ago},{N_months_ago}) counts from today, not from a period's first day, so no declared token names the month before last.lastPeriodBeforetherefore computes the day: it resolves thelast_*START throughresolveDateMacros(the display zone, like every other token), moves it back one week / month / quarter / year with UTC calendar arithmetic, and takes the day before thatlast_*start as the end. The result is an ISO day, whichresolveDateMacrospasses through. No token is invented.rollingPair(wasforwardRollingPair) now also matches{N_days_ago}with{today}. That window is N + 1 days (last_7_daysat 2026-07-15 is 07-08..07-15, measured), and moves back by N + 1:{(2N+1)_days_ago}…{(N+1)_days_ago}. It used to become{N_days_ago}…{yesterday}, N days overlapping the current window. The forward branch now writes{1_day_ago}instead of{yesterday}, because{yesterday}is now itself moved; the resolved window is unchanged.substituteTokensnow takes a replacer), sotoday→yesterdayis never carried on to2_days_ago.kind: 'previousYear'builtnew Date(y - 1, 1, 29), which is 1 March, so every window seen from 2028-02-29 was re-resolved at 2027-03-01 (this_monthcompared with March 2027). The day is clamped to the shifted month's length, 28 February.compareToTrendLabelKey: a{yesterday}orlast_*token, and a backward rolling window, readvsPreviousPeriod(they readvsYesterday,vsLastWeek,vsLastMonth,vsLastQuarter,vsLastYear). No existingdashboard.trend.*key names "the month before last", andvsPreviousPeriod("vs previous period", 较上期) is exact for each, so no new key, no locale or fallback change. The check runs first, sincelast_month_startalso containsmonth_start.NEXT_TO_CURRENT_TOKENS(my fix(core): compareTo on a forward date range (next month, next quarter, next 30 days) compares with the period just before it, not with itself #30196 text): it saidnext_week_*/next_year_*have no_endin the macro vocabulary. The spec declaresnext_week_endandnext_year_end; it is this package's resolver (date-macros.ts) that lacks them. The comment now says so; the mapping is unchanged.Why
#30197, filed from #30196's Acceptance notes. Governing text: the
compare-to.tsdocblock, "kind: 'previousPeriod'— the equal-length window immediately before the current one", andpreviousYear= "same week / month / quarter, one year earlier". No spec change, no newcompareTokind, no executor change.Tests
dashboard-filters.presetWindows-29116.test.ts: the compareTo case pins all 16 presets at 2026-07-15 (both kinds and the label); the fivelast_*/yesterdayrows and the threelast_N_daysrows move, the eight others keep fix(core): compareTo on a forward date range (next month, next quarter, next 30 days) compares with the period just before it, not with itself #30196's values. New for every preset on all six reference dates: the previous window ends the day before the current window starts, with the same day count for a day, a week or a rolling window, and from the 1st for a month, quarter or year. New for every preset:previousYearfrom 2028-02-29 equals resolving the filter at 2027-02-28.compare-to.test.ts: yesterday, last week, last month (also from 2026-03-31, February then January), last quarter and last year across a year boundary,{7_days_ago}…{today}and a$between{30_days_ago}…{today}, a mixedlast_month_start…current_month_endwindow moved bound by bound, the leap-daypreviousYearcase, and the labels (a lone{today}still readsvsYesterday).ObjectMetricWidget.compareTo.pastPresets-30197.test.tsx(rendered, the registeredobject-metricblock, the fix(core): compareTo on a forward date range (next month, next quarter, next 30 days) compares with the period just before it, not with itself #30196 harness):last_month(上月),yesterdayandlast_7_dayseach show20%against exactly the expected previous window, under "vs previous period", and not the stale label.Acceptance notes
tsxprobe of 16 presets × 8 reference dates × 2 kinds plus labels,mainff12aed3against this branch. Unchanged:this_quarter,this_year,next_quarterin full;today,this_week,this_month,next_month,next_30_daysin every row exceptpreviousYearat 2028-02-29 (the leap-day fix; e.g.this_month2027-03-01..03-31 → 2027-02-01..02-28). Changed as intended:yesterday,last_week,last_month,last_quarter,last_year,last_7_days,last_30_days,last_90_days(previousPeriod rows and label, plus their 2028-02-29 previousYear row where it moves).last_30_daysat 2026-07-15: this branch 2026-05-15..06-14; the executor (shiftRange, measured on Dashboard compareTo on a forward date preset (下月, 下季度, 未来 30 天) compares the window with itself #30140) 2026-05-15..06-14. On calendar presets the two still differ by design: the executor counts days, the inline path steps whole periods.next_week_end/next_year_end, which the spec declares (see the docblock correction above).Verification
Suites, type-check, lint, ablations
os-verify-lock:pnpm --dir ui exec vitest run --maxWorkers=3 packages/core/exit 0 (232 files, 4,321 passed, 27 skipped);packages/plugin-dashboard/exit 0 (202 files, 1,928 passed, 6 skipped).pnpm run type-checkin core and plugin-dashboard: exit 0.npx eslinton the touched files: 0 errors (warnings only,no-explicit-any, as in the surrounding code).scripts/ablation-replace.mjs, each red then restored to HEAD):lastPeriodBeforenot called): 12 failed, covering the five past-token pins, the five 29116 rows, and the renderedlast_monthandyesterdayrows;ROLLING_DAYS_RElimited tofrom_now): 6 failed (the rolling pin, the label pin, the threelast_N_daysrows, the renderedlast_7_daysrow);previousYearwindow moves);dispatch-gates --commands, 35): see the report on Inline compareTo previousPeriod: backward presets (上月, 上季度, 昨天, 上周, 去年) compare a window with itself, last_N_days compares N+1 days with N #30197.Human Minimum
packages/specholds no runtime logic. (not touched)main, one pull request.packages/spectouched: n/a.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01WGufzijmF7yUSk5ga9jRkh