>
>
> Hi Minseok,
>
> Thank you for the thorough verification and the excellent analysis — and
> thank you for voting +0 with such a clear write-up instead of a silent -1.
>
> We have reproduced the failure locally and can confirm your findings 100%:
>
> * Same failing test: DateFormatTest.readCn(ExcelFormat)[1]
> (assertion at DateFormatTest.java:60), preceded by
> CsvRowTest#csvWrite_withSqlDateAndTime_producesCorrectFile.
> * With a Korean JVM default locale the ordered run fails; running
> DateFormatTest alone passes. Your diagnosis is exactly right:
> NumberDataFormatterUtils keeps a single DataFormatter per thread in a
> ThreadLocal and does not re-check (use1904windowing, locale,
> useScientificFormat) on subsequent calls. The low-level CSV write path
> (CsvSheet#buildCellValue) populates the cache with a formatter bound to
> the JVM default locale (CsvWorkbook passes a null locale, which
> DataFormatter resolves to Locale.getDefault()) and never clears it, so
> a later request for Locale.CHINA on the same thread reuses the
> Korean-initialized formatter ("오전" instead of "上午").
>
> To answer your specific questions:
>
> 1. Can this occur during normal application usage?
> It is essentially limited to the direct low-level CSV API
> (CsvWorkbook/CsvSheet) and to direct use of the public
> NumberDataFormatterUtils.format() utility. The managed read/write flows
> (FesodSheet.read(...)/write(...)) clear all ThreadLocal caches in
> WriteContextImpl.finish() and ExcelAnalyserImpl, including on exception
> paths, so two consecutive managed operations with different locales do
> not contaminate each other.
>
> 2. Is the direct CSV path expected to clear this cache?
> No — currently it does not, and that is a gap on our side. The low-level
> path has no cleanup hook today.
>
> 3. Does this block the release candidate?
> This is a pre-existing, legacy issue in the thread-local formatter
> cache,
> inherited from the original codebase — it was not introduced by this
> release candidate, and RC3 contains no change in this area. That said,
> it is a real correctness issue and we very much welcome fixing it: we
> intend to track it as a standalone improvement (keying the cached
> DataFormatter on its configuration parameters, clearing the cache when
> the low-level CSV writer closes, and adding an order-independent
> regression test), and contributions from the community are more than
> welcome.
>
> Your verification with NumberDataFormatterUtils.removeThreadLocalCache()
> matches our own testing exactly — thank you again for pinning down the root
> cause so precisely. It made confirmation and the follow-up work much
> easier.
>
> Best regards,
> Zhe Zhang