Repository navigation
fix: key the date format cache by format index and string - #1304
hanzhe-one wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Thanks @hanzhe-one — I reproduced the bug and verified the fix locally (Windows 11, JDK 17).
Root cause: DATE_THREAD_LOCAL is keyed by the format index alone. Custom indexes are workbook-scoped, so the same index can map to different format strings. Calling DateUtils.isADateFormat(164, "yyyy-mm-dd") then (164, "0.00") returns true twice; the reverse order returns false twice, while isADateFormatUncached gives the correct pair.
Verification
- Red: with only
ExcelDateFormatDetectorreverted (your tests kept), 3 new tests fail as described — both orders plus the null format string; the internal-index test passes either way. - Green:
DateUtilsTest94/94. - Full suite: 60 + 1,793 tests, 0 failures;
spotless:checkclean. I didn't hit theUrlImageConverterTestloopback errors here, consistent with your sandbox note.
Design check: Mapping a null format string to "" is behavior-preserving — isADateFormatUncached treats both as empty after the internal-index check — and the NUL (0x00) separator keeps the composite key unambiguous. The cache lifecycle is unchanged: removeThreadLocalCache() still runs from ExcelAnalyserImpl.close and WriteContextImpl.finish, so normal read/write paths remain operation-scoped.
One nit (non-blocking): test_isADateFormat_Cache now asserts size and containsValue(true), but the key shape is the point of the fix — asserting the exact composite key (formatIndex + NUL + formatString) would pin it directly.
LGTM — the cache now agrees with the uncached detector, and both orders are covered.
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues remain for the date-format cache-key change.
No open issues 🎉
What changed in this PR
Fixes #1303 by making date-format cache results depend on both the format index and format string, preventing stale results when workbooks reuse an index for different formats.
Changes:
- Uses a composite string cache key with stable handling of null format strings.
- Updates cache assertions and adds regression tests for differing strings, call order, null strings, and built-in date indexes.
- Preserves detection logic, public signatures, and cache cleanup behavior.
| File | Description |
|---|---|
fesod-sheet/src/test/java/org/apache/fesod/sheet/util/DateUtilsTest.java |
Updates cache assertions and adds regression coverage. |
fesod-sheet/src/main/java/org/apache/fesod/sheet/util/ExcelDateFormatDetector.java |
Keys cached results by format index and string. |
Review effort: Balanced
Purpose of the pull request
Closed: #1303
ExcelDateFormatDetectorcached date-format detection in a thread-localMap<Short, Boolean>keyed by the format index alone. Custom format indexes (>= 164) are defined per workbook, so the same index can map to different format strings. Once an index was cached, later queries with a different string returned the earlier result:Reverse order made a date format report
false.isADateFormatUncachedreturns the correct values, so the cache disagreed with the detector.What's changed?
Map<String, Boolean>keyed byformatIndexplus the format string; a null format string maps to a stable key.DateUtilsTest.test_isADateFormat_Cachenow asserts the new key shape instead of reflecting on aShortkey.The cache is cleared in
WriteContextImpl.finishandExcelAnalyserImpl.close, so a completed read or write normally starts fresh. This change removes the reliance on that clearing for correctness when the same thread queries one index with different format strings.Validation
./mvnw -pl fesod-sheet test: 1,793 tests, 0 failures.DateUtilsTest: 94 tests, 0 failures../mvnw spotless:check: passes.The only errors in that run are 10 in
UrlImageConverterTest, allIOException: Unable to establish loopback connectionwhen the test starts anHttpServer. The same 10 errors occur on unmodifiedmainin this environment, so they are a sandbox networking restriction rather than a regression from this change; CI runs without that restriction.Note: open PR #1260 also modifies
ExcelDateFormatDetectorwhen centralizing thread-local cleanup; whichever lands second needs a trivial rebase.Checklist