Skip to content

fix(ui): export the transaction time column in the same 口径 as the cell - #229

Merged
argszero merged 1 commit into
mainfrom
fix/tx-csv-time-local
Sep 14, 2026
Merged

fix(ui): export the transaction time column in the same 口径 as the cell#229
argszero merged 1 commit into
mainfrom
fix/tx-csv-time-local

Conversation

@argszero

Copy link
Copy Markdown
Owner

Summary

The transactions CSV export printed the time column in a different 口径 than the table cell it sits next to: exportTxCsv wrote the view row's raw t.time (the UTC string the API returns, which txsToView does not convert), while the cell renders the very same field through fmtPrecise() — i.e. local time. In a UTC+8 session one and the same row reads 23:04 in the table and 15:04 in 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 uses fmtPrecise(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 changed app.js (?v=20260914-6).
  • No config / data-structure change, no new i18n key, no Rust change.

Tests

  • cargo test235 passed (unchanged; the change is JS-only)
  • cargo fmt --check — exit 0
  • cargo clippy --all-targets -- -D warnings — clean
  • node --check on all four ui/js/*.js
  • jsdom probe (real ui/index.html + api.js/data.js/i18n.js/app.js, only fetch stubbed): boots three transactions, reads the rendered cell text and the bytes of the exported Blob (captured from URL.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 both TZ=Asia/Shanghai and TZ=America/New_York.
    • The probe asserts a non-UTC process TZ first: under TZ=UTC the two 口径 coincide and the value divergence is invisible (it exists only in the format then), so a UTC run would be meaningless.
    • A/B legs: pre-change {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

  • Branch naming follows the convention (fix/…)
  • Commit message uses Conventional Commits (fix(ui): …)
  • Single responsibility, minimal change (3 files, +8/−3)

`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.
@argszero
argszero merged commit d1faab6 into main Sep 14, 2026
1 check passed
@argszero
argszero deleted the fix/tx-csv-time-local branch September 14, 2026 00:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant