fix(ui): export the transaction time column in the same 口径 as the cell - #229
Merged
Conversation
`exportTxCsv` wrote the view row's raw `t.time` — the UTC string the API returns, which `txsToView` does not convert — while the table cell renders that same field through `fmtPrecise()` (local time, #139 / rant 2026-08-24T12:38:44). In a UTC+8 session one and the same row therefore reads `23:04` in the table and `15:04` in the exported file (west of Greenwich the sign flips). This is the class of divergence C2054/C2055 already closed for the 点数 column: "the export covers the currently visible rows, so the column must use the same 口径 as the cell — otherwise the screen says -3.7 and the file says 3.7". Fix: print the time column with the very helper that renders the cell (`fmtPrecise(t.time)`) instead of keeping a second copy of "time to string". Verified with a jsdom probe (real ui/index.html + the four scripts, only `fetch` stubbed) that boots three transactions, reads the rendered cell and the bytes of the exported Blob: pre-change red on the time-column assertion only; fixed tree 6/6, in Asia/Shanghai and America/New_York. The probe also asserts the process TZ is not UTC, since under TZ=UTC the two 口径 coincide and the defect is invisible.
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.
Summary
The transactions CSV export printed the time column in a different 口径 than the table cell it sits next to:
exportTxCsvwrote the view row's rawt.time(the UTC string the API returns, whichtxsToViewdoes not convert), while the cell renders the very same field throughfmtPrecise()— i.e. local time. In a UTC+8 session one and the same row reads23:04in the table and15:04in the downloaded file (west of Greenwich the sign flips). A CSV whose header is localized (时间) and whose values disagree with the screen is a trap for anyone reconciling the file against the UI.This is the same class of divergence the project already closed for the 点数 column in #196 (C2054/C2055), whose own comment states the rule: "the export covers the currently visible rows, so the column must use the same 口径 as the cell — otherwise the screen says -3.7 and the file says 3.7". Time is simply the column that was never brought along.
Provenance: the cell moved to precise local time in #139 (rant 2026-08-24T12:38:44); that commit updated the cell but not the other consumer of the same field (
exportTxCsv, added earlier in #68).Related Issue
N/A — no open issue. Background: #139 (cell 口径 changed to local), #196 (the same divergence fixed for the 点数 column).
Changes
ui/js/app.js— the CSV 时间 column now usesfmtPrecise(t.time), the same helper that renders the cell, instead of a second copy of "timestamp to string" (one line + a comment stating why the two must stay同源).ui/README.md— the CSV convention section now records that every column shares the cell's 口径 (with time as the second instance after 点数).ui/index.html— cache-bust for the changedapp.js(?v=20260914-6).Tests
cargo test— 235 passed (unchanged; the change is JS-only)cargo fmt --check— exit 0cargo clippy --all-targets -- -D warnings— cleannode --checkon all fourui/js/*.jsui/index.html+api.js/data.js/i18n.js/app.js, onlyfetchstubbed): boots three transactions, reads the rendered cell text and the bytes of the exported Blob (captured fromURL.createObjectURL), and asserts that each CSV column equals its cell — time (the axis), plus type / pts / tokens as controls. Pre-change tree: 5/6, red on the time column only. Fixed tree: 6/6, exit 0, under bothTZ=Asia/ShanghaiandTZ=America/New_York.TZ=UTCthe two 口径 coincide and the value divergence is invisible (it exists only in the format then), so a UTC run would be meaningless.{time}· mirror-image repair (make the cell print UTC so the two "agree"){cell-local}— disjoint from the pre-change set, i.e. the instrument rejects consistency-by-breaking-the-cell · half fix (append":00"and stay UTC){time}(same assertion, different input — not mutually exclusive with the pre-change leg, recorded as such) · control-teeth leg (CSV type field printed raw){type-control}· fixed tree{}.Checklist
fix/…)fix(ui): …)