You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Task] Implement more commonly used converter classes #1017
During usage, we may need to convert read or written data into specific formats. Apache Fesod (Incubating) provides a flexible converter mechanism that allows users to define custom data conversion rules to meet various business requirements. Many converter classes are already built in, but some are still missing.
How to complete
Please link this issue in the description of the PR.
This will be a long-term task, allowing all the volunteers to divide it into multiple PRs for completion. Each PR can contain one or more converters, and each converter needs to provide the corresponding unit test code.
Only classes compatible with JDK 8 are supported. Each converter must implement the org.apache.fesod.sheet.converters.Converter interface, and please leave a comment outlining your specific implementation proposal.
Task List
The following are some conversions that are currently required
Please feel free to suggest any type converters you require, and please leave a comment in this issue.
The new proposal needs to be published for at least 24 hours. If there are no objections during this period, please feel free to submit your PR at any time. These will be added to the task list and assigned to volunteers later.
changed the title [-][Task] Implement more commonly used Converter classes[/-][+][Task] Implement more commonly used converter classes[/+]on Aug 16, 2026
Here is an implementation proposal for java.time.ZonedDateTime converters, following the established LocalDateTime / LocalDate pattern:
1. Proposed Converter Family (org.apache.fesod.sheet.converters.zoneddatetime)
ZonedDateTimeDateConverter (Write -> Excel DATE cell):
Emits WriteCellData(value.toLocalDateTime()) with default date format (yyyy-MM-dd HH:mm:ss).
ZonedDateTimeNumberConverter (Bidirectional Excel NUMBER serial):
Read: Parses Excel numeric serial to LocalDateTime (respecting use1904windowing), then assigns ZoneId.systemDefault() (localDateTime.atZone(ZoneId.systemDefault())).
Write: Converts value.toLocalDateTime() to numeric serial via DateUtil.getExcelDate(value.toLocalDateTime(), use1904).
Read: Parses according to @DateTimeFormat if specified, or standard DateUtils patterns, attaching ZoneId.systemDefault() when no zone/offset is present in the input string.
Write: Formats date-time using @DateTimeFormat (default yyyy-MM-dd HH:mm:ss) and configured Locale.
2. Timezone & Lossiness Semantics
Numeric & Date cells: Native Excel sheets store temporal values as zone-less numbers/dates. Writing ZonedDateTime necessarily preserves the local wall-clock time (zonedDateTime.toLocalDateTime()) while omitting the ZoneId/offset in the Excel file.
Reading numeric cells: Converts to LocalDateTime and attaches ZoneId.systemDefault(), matching the convention used across existing Date / LocalDateTime conversions.
String cells: When explicit zone/offset patterns (e.g. yyyy-MM-dd'T'HH:mm:ssXXX) are used via @DateTimeFormat, the offset/zone can be parsed or emitted verbatim.
3. Registration & Test Coverage
Register ZonedDateTimeNumberConverter and ZonedDateTimeStringConverter in DefaultConverterLoader.initAllConverter().
Register ZonedDateTimeDateConverter and ZonedDateTimeStringConverter in DefaultConverterLoader.initDefaultWriteConverter().
Add unit tests in ConverterTest (supportJavaTypeKey, supportExcelTypeKey, read/write assertions for Date, Number, String).
Add round-trip integration coverage in ConverterDataTest across all supported formats (XLSX, XLS, CSV, etc.).
Validate immutability in DefaultConverterLoaderTest.
Feedback and thoughts from the community are welcome!
BTW, the unit test class can be independently added to the org.apache.fesod.sheet.converter package. For example, add a ZonedDateTimeConverterTest class.
Welcome, the proposal is to be published for 24 hours, if no objections are raised, the task will be assigned to you.
I’d like to work on the java.sql.Timestamp converter support.
My proposed approach is to follow the existing Date / LocalDateTime converter pattern and add a dedicated Timestamp converter family under org.apache.fesod.sheet.converters:
TimestampDateConverter
Default write path for Timestamp
Preserve the existing date-format handling used by the other temporal converters
TimestampNumberConverter
Read Excel numeric date values into Timestamp
Write Timestamp values as Excel date serials
Reuse the existing date utilities and respect use1904windowing
TimestampStringConverter
Read and write string values using the existing DateUtils formatting/parsing behavior
Respect @DateTimeFormat and the configured locale
For registration, I plan to follow the current LocalDateTime setup in DefaultConverterLoader:
register the Number and String converters in initAllConverter()
register the Date converter as the default write converter
register the String converter for string-formatted writes
Since converter lookup is keyed by the declared Java class, the existing java.util.Date converters do not automatically cover fields declared as java.sql.Timestamp, so I would keep the change scoped to adding explicit Timestamp support rather than changing the converter lookup mechanism.
For tests, I plan to add a dedicated TimestampConverterTest covering the converter keys and read/write behavior, including the relevant date-format / 1904-windowing cases, plus the existing loader or round-trip coverage where appropriate.
I’ll keep the implementation JDK 8 compatible and limited to the Timestamp slice of this issue.
If this direction looks good, I’d be happy to take it.
BTW, the unit test class can be independently added to the org.apache.fesod.sheet.converter package. For example, add a ZonedDateTimeConverterTest class.
Welcome, the proposal is to be published for 24 hours, if no objections are raised, the task will be assigned to you.
It has been assigned to you. Please refer to the code contribution guidelines and feel free to submit a PR at any time, and please link this issue in the description of the PR.
It has been assigned to you. Please refer to the code contribution guidelines and feel free to submit a PR at any time, and please link this issue in the description of the PR.
I'd like to work on the java.sql.Clob converter (still unassigned in the task list).
Proposed approach, following the existing String converter family (StringStringConverter, StringNumberConverter) under a new org.apache.fesod.sheet.converters.clob package:
Read: builds a java.sql.Clob from the cell's string value via javax.sql.rowset.serial.SerialClob (JDK 8 compatible, no external deps), i.e. new SerialClob(cellData.getStringValue().toCharArray()).
Write: extracts the full contents with clob.getSubString(1, (int) clob.length()) and wraps it in a WriteCellData<>(...), matching StringStringConverter's write path.
Registration: add to DefaultConverterLoader.initAllConverter() (as the String-keyed converters are), keyed on Clob.class / CellDataTypeEnum.STRING.
Tests: add a ClobConverterTest under org.apache.fesod.sheet.converter (same location as StringPathnameImageConverterTest/CustomConverterTest), covering supportJavaTypeKey/supportExcelTypeKey, round-trip read/write, and an empty-string edge case. SQLException from SerialClob construction will propagate per the Converter interface's throws Exception contract.
Scope is limited to this one converter — happy to take another (e.g. java.sql.Clob's counterpart on read-only numeric/boolean cells) as a follow-up if useful. Will link this issue in the PR per the contribution guide.
I'd like to work on the java.sql.Clob converter (still unassigned in the task list).
...
Write: extracts the full contents with clob.getSubString(1, (int) clob.length()) and wraps it in a WriteCellData<>(...), matching StringStringConverter's write path.
FYI, regarding string slicing, please note that the maximum text length in Excel cells is 32767. If possible, it is recommended to adhere to this limit and provide similar test cases in the unit tests.
Welcome, the proposal is to be published for 24 hours, if no objections are raised, the task will be assigned to you.
I'd like to work on java.time.OffsetDateTime converter support.
Proposed approach: follow the existing LocalDateTime / ZonedDateTime converter family pattern, adding three converters under org.apache.fesod.sheet.converters:
Each will implement the Converter interface and come with corresponding JUnit 5 tests, mirroring the structure of the recently added ZonedDateTime converter tests.
I'd like to work on java.time.LocalTime converter support.
Fesod already has LocalDate / LocalDateTime converters, and WriteCellData already maps java.sql.Time via toLocalTime().atDate(DateUtils.EPOCH). A dedicated LocalTime converter family would close that gap for time-of-day fields (DB TIME columns, business hours, schedules) without requiring users to fall back to String or LocalDateTime.
1. Proposed Converter Family (org.apache.fesod.sheet.converters.localtime)
Following the existing LocalDate / LocalDateTime pattern:
LocalTimeDateConverter (Write -> Excel DATE cell):
Emits WriteCellData(value.atDate(DateUtils.EPOCH)) with default format HH:mm:ss.
Reuses the same epoch-date convention already used for java.sql.Time in WriteCellData / CsvCell.
LocalTimeNumberConverter (Bidirectional Excel NUMBER serial):
Read: DateUtils.getLocalDateTime(serial, use1904windowing).toLocalTime(), so both Excel-native time fractions (0.5 = 12:00:00) and full datetime serials round-trip to the same wall-clock time.
Write: DateUtil.getExcelDate(value.atDate(DateUtils.EPOCH), use1904), consistent with the DATE write path.
Read / Write: parse and format with @DateTimeFormat if present, otherwise HH:mm:ss (and HH:mm when the input has no seconds).
Respect the configured Locale.
Small DateUtils additions will be needed (mirroring parseLocalDate / format(LocalDate)):
defaultLocalTimeFormat = "HH:mm:ss"
parseLocalTime(...) / format(LocalTime, ...)
time-only pattern detection for HH:mm:ss / HH:mm (current switchDateFormat only covers date/datetime lengths)
2. Time-only Semantics
Excel has no native time-only cell type. Time is stored as a datetime serial (or a day fraction) and displayed via number format.
Writing: preserve the wall-clock time and attach DateUtils.EPOCH (1970-01-01) as the date component, then apply HH:mm:ss so Excel shows time only.
Reading: drop any date component with toLocalTime(). A numeric cell of 0.5 and a datetime serial that happens to be 12:00:00 both become LocalTime.of(12, 0, 0).
This is the time-only counterpart of LocalDate (which keeps the date and zeros the time).
3. Registration & Test Coverage
Register LocalTimeNumberConverter and LocalTimeStringConverter in DefaultConverterLoader.initAllConverter().
Register LocalTimeDateConverter and LocalTimeStringConverter in DefaultConverterLoader.initDefaultWriteConverter().
Add a dedicated LocalTimeConverterTest under org.apache.fesod.sheet.converter, covering converter keys, DATE/NUMBER/STRING read-write, @DateTimeFormat, use1904windowing, and the date-dropping behavior.
Add round-trip coverage in ConverterDataTest where appropriate.
Validate loader immutability still holds in DefaultConverterLoaderTest.
Scope is limited to java.time.LocalTime (JDK 8). java.sql.Time can be a follow-up if useful; converter lookup is keyed by the declared Java class, so existing Date converters do not cover LocalTime fields.
If this direction looks good, I’d be happy to take it.
Proposal for three types that are not on the task list yet. I checked the current behaviour on main (4e3f3aa) with a bean per type, and all of them fail on read and on write:
write Instant -> ExcelWriteDataConvertException: Can not find 'Converter' support class Instant.
write java.sql.Date -> ExcelWriteDataConvertException: Can not find 'Converter' support class Date.
write YearMonth -> ExcelWriteDataConvertException: Can not find 'Converter' support class YearMonth.
write UUID -> ExcelWriteDataConvertException: Can not find 'Converter' support class UUID.
read Instant -> ExcelWriteDataConvertException: Can not find 'Converter' support class Instant.
read java.sql.Date -> ExcelWriteDataConvertException: Can not find 'Converter' support class Date.
read YearMonth -> ExcelWriteDataConvertException: Can not find 'Converter' support class YearMonth.
read UUID -> ExcelWriteDataConvertException: Can not find 'Converter' support class UUID.
java.sql.Date is worth calling out separately: it extends java.util.Date, which does have converters, but the converter map is keyed by the exact class, so a java.sql.Date field gets nothing. It is the sibling of java.sql.Timestamp, which is already on the list.
InstantDateConverter (Excel DATE): write Date.from(value) as WriteCellData<Date>; read cellData.getDateValue().toInstant().
InstantNumberConverter (Excel NUMBER serial): read and write through LocalDateTime like the localdatetime family, so use1904windowing and the number format keep working; atZone(ZoneId.systemDefault()).toInstant().
InstantStringConverter (Excel STRING): DateUtils.format(...) / parseDate(...) with the @DateTimeFormat value, falling back to the default pattern.
Proposal 2 - java.sql.Date and java.sql.Time (converters/sqldate/, converters/sqltime/)
Mirror the existing converters/date/ family one to one (*DateConverter, *NumberConverter, *StringConverter), with toLocalDate() / toLocalTime() as the intermediate, and register them in DefaultConverterLoader. Same shape as the java.sql.Timestamp proposal that is already assigned, so the sql family stays consistent.
Excel has no month type, so YearMonthStringConverter as yyyy-MM plus YearMonthNumberConverter through the first day of the month, which keeps sorting and date arithmetic in the sheet working.
All three proposals are JDK 8 only, implement org.apache.fesod.sheet.converters.Converter, and would come with unit tests per converter (write, read and a round trip through xlsx) plus the DefaultConverterLoader registration.
I will leave this comment for the 24 hours mentioned above and then open the PRs, one type family per PR. If you would rather have them in a different shape (for example Instant as a string only, or YearMonth as a DATE cell of the first day), tell me and I will adjust before the PR.
converters/sqldate, converters/sqltime, converters/instant and converters/yearmonth, each with a round trip test over xlsx, xls and csv. They are in one PR because all of them register in DefaultConverterLoader and separate PRs would conflict there; I can split it if you prefer.
Verification on my machine with Temurin 1.8.0_472: 928 tests, 0 failures, and spotless:check passes.
I'd like to propose a follow-up batch of four JDK 8 compatible types that are neither on the task list nor proposed yet (verified against DefaultConverterLoader and this thread): java.time.Month, java.time.DayOfWeek, java.time.Period and java.time.Duration.
Proposed approach - one bidirectional STRING converter per type, following the *StringConverter pattern:
MonthStringConverter (converters/month): writes Month#getDisplayName(TextStyle.FULL, locale) respecting GlobalConfiguration.locale (or a @DateTimeFormat custom pattern with numeric uuuu-MM style values also accepted on read); reads case-insensitively via Month#valueOf and 1-12 numerically.
DayOfWeekStringConverter (converters/dayofweek): same shape as above over DayOfWeek, with 1-7 numeric read support (ISO-8601 Monday=1).
Each ships with JUnit 5 unit tests (round-trip, locale handling where applicable, invalid input reported as ExcelDataConvertException instead of being silently coerced) and registration in DefaultConverterLoader. Happy to split them into one PR per type or batch two-and-two, whichever maintainers prefer.
I'd like to propose and take the missing number converter for java.time.Year — the follow-up to YearStringConverter, which landed via #1087 (background discussion in #1216).
Current behaviour on main (verified at bf9bf92): Year ships only the STRING converter, so the (Year, NUMBER) read key is unmapped and a numeric year column fails on read:
read a cell containing 2026 into a Year field
-> ExcelDataConvertException: Converter not found, convert NUMBER to java.time.Year
Date-formatted cells fail the same way, since they are NUMBER cells at read time. The sibling date-like types (LocalDate, LocalTime, OffsetDateTime, java.util.Date) each ship a number converter, so this closes the gap #1087 left in the family.
Proposed converter — YearNumberConverter under converters/year, following the *NumberConverter pattern:
a date-formatted cell → the year of the Excel serial date it represents, consistent with the siblings;
any other numeric cell → the year itself (2026 → Year.of(2026); a serial reading would give 1905, which is not what a year column means);
read side only: Year keeps writing as STRING through YearStringConverter, unchanged.
Implementation is up as #1217, with a unit test plus an end-to-end read test. It was opened earlier today as a bug fix, before the reclassification in #1216 — apologies for skipping the 24-hour notice; happy to hold it if that step should apply.
The plain-number branch is the design point worth a look: if strict family consistency is preferred (always read as a date serial), it can be switched.
Activity
[-][Task] Implement more commonly used Converter classes[/-][+][Task] Implement more commonly used converter classes[/+]alexsmolya commentedon Aug 16, 2026
Here is an implementation proposal for
java.time.ZonedDateTimeconverters, following the establishedLocalDateTime/LocalDatepattern:1. Proposed Converter Family (
org.apache.fesod.sheet.converters.zoneddatetime)ZonedDateTimeDateConverter(Write -> ExcelDATEcell):WriteCellData(value.toLocalDateTime())with default date format (yyyy-MM-dd HH:mm:ss).ZonedDateTimeNumberConverter(Bidirectional ExcelNUMBERserial):LocalDateTime(respectinguse1904windowing), then assignsZoneId.systemDefault()(localDateTime.atZone(ZoneId.systemDefault())).value.toLocalDateTime()to numeric serial viaDateUtil.getExcelDate(value.toLocalDateTime(), use1904).ZonedDateTimeStringConverter(Bidirectional ExcelSTRINGcell):@DateTimeFormatif specified, or standardDateUtilspatterns, attachingZoneId.systemDefault()when no zone/offset is present in the input string.@DateTimeFormat(defaultyyyy-MM-dd HH:mm:ss) and configuredLocale.2. Timezone & Lossiness Semantics
ZonedDateTimenecessarily preserves the local wall-clock time (zonedDateTime.toLocalDateTime()) while omitting theZoneId/offset in the Excel file.LocalDateTimeand attachesZoneId.systemDefault(), matching the convention used across existingDate/LocalDateTimeconversions.yyyy-MM-dd'T'HH:mm:ssXXX) are used via@DateTimeFormat, the offset/zone can be parsed or emitted verbatim.3. Registration & Test Coverage
ZonedDateTimeNumberConverterandZonedDateTimeStringConverterinDefaultConverterLoader.initAllConverter().ZonedDateTimeDateConverterandZonedDateTimeStringConverterinDefaultConverterLoader.initDefaultWriteConverter().ConverterTest(supportJavaTypeKey,supportExcelTypeKey, read/write assertions for Date, Number, String).ConverterDataTestacross all supported formats (XLSX, XLS, CSV, etc.).DefaultConverterLoaderTest.Feedback and thoughts from the community are welcome!
delei commentedon Aug 16, 2026
Hi, @alexsmolya , welcome !
SGTM, +1.
BTW, the unit test class can be independently added to the
org.apache.fesod.sheet.converterpackage. For example, add aZonedDateTimeConverterTestclass.Welcome, the proposal is to be published for 24 hours, if no objections are raised, the task will be assigned to you.
SyedIshmumAhnaf commentedon Aug 16, 2026
I’d like to work on the java.sql.Timestamp converter support.
My proposed approach is to follow the existing Date / LocalDateTime converter pattern and add a dedicated Timestamp converter family under org.apache.fesod.sheet.converters:
For registration, I plan to follow the current LocalDateTime setup in DefaultConverterLoader:
Since converter lookup is keyed by the declared Java class, the existing java.util.Date converters do not automatically cover fields declared as java.sql.Timestamp, so I would keep the change scoped to adding explicit Timestamp support rather than changing the converter lookup mechanism.
For tests, I plan to add a dedicated TimestampConverterTest covering the converter keys and read/write behavior, including the relevant date-format / 1904-windowing cases, plus the existing loader or round-trip coverage where appropriate.
I’ll keep the implementation JDK 8 compatible and limited to the Timestamp slice of this issue.
If this direction looks good, I’d be happy to take it.
delei commentedon Aug 17, 2026
Hi, @SyedIshmumAhnaf
SGTM, +1.
Welcome, the proposal is to be published for 24 hours, if no objections are raised, the task will be assigned to you.
delei commentedon Aug 17, 2026
Hi, @alexsmolya
It has been assigned to you. Please refer to the code contribution guidelines and feel free to submit a PR at any time, and please link this issue in the description of the PR.
delei commentedon Aug 17, 2026
Hi, @SyedIshmumAhnaf
It has been assigned to you. Please refer to the code contribution guidelines and feel free to submit a PR at any time, and please link this issue in the description of the PR.
AhmedYoussef98 commentedon Aug 17, 2026
I'd like to work on the
java.sql.Clobconverter (still unassigned in the task list).Proposed approach, following the existing
Stringconverter family (StringStringConverter,StringNumberConverter) under a neworg.apache.fesod.sheet.converters.clobpackage:ClobStringConverter(bidirectional, ExcelSTRINGcell)java.sql.Clobfrom the cell's string value viajavax.sql.rowset.serial.SerialClob(JDK 8 compatible, no external deps), i.e.new SerialClob(cellData.getStringValue().toCharArray()).clob.getSubString(1, (int) clob.length())and wraps it in aWriteCellData<>(...), matchingStringStringConverter's write path.Registration: add to
DefaultConverterLoader.initAllConverter()(as theString-keyed converters are), keyed onClob.class/CellDataTypeEnum.STRING.Tests: add a
ClobConverterTestunderorg.apache.fesod.sheet.converter(same location asStringPathnameImageConverterTest/CustomConverterTest), coveringsupportJavaTypeKey/supportExcelTypeKey, round-trip read/write, and an empty-string edge case.SQLExceptionfromSerialClobconstruction will propagate per theConverterinterface'sthrows Exceptioncontract.Scope is limited to this one converter — happy to take another (e.g.
java.sql.Clob's counterpart on read-only numeric/boolean cells) as a follow-up if useful. Will link this issue in the PR per the contribution guide.delei commentedon Aug 17, 2026
Hi, @AhmedYoussef98
SGTM, +1.
FYI, regarding string slicing, please note that the maximum text length in Excel cells is 32767. If possible, it is recommended to adhere to this limit and provide similar test cases in the unit tests.
Welcome, the proposal is to be published for 24 hours, if no objections are raised, the task will be assigned to you.
Mikkey-f commentedon Aug 20, 2026
I'd like to work on
java.time.OffsetDateTimeconverter support.Proposed approach: follow the existing
LocalDateTime/ZonedDateTimeconverter family pattern, adding three converters underorg.apache.fesod.sheet.converters:OffsetDateTimeStringConverter— OffsetDateTime ↔ StringOffsetDateTimeNumberConverter— OffsetDateTime ↔ Number (epoch-based, consistent with existing Date/LocalDateTime numeric conversion)OffsetDateTimeDateConverter— OffsetDateTime ↔ java.util.DateEach will implement the
Converterinterface and come with corresponding JUnit 5 tests, mirroring the structure of the recently addedZonedDateTimeconverter tests.leehaut commentedon Aug 22, 2026
I'd like to work on
java.time.LocalTimeconverter support.Fesod already has
LocalDate/LocalDateTimeconverters, andWriteCellDataalready mapsjava.sql.TimeviatoLocalTime().atDate(DateUtils.EPOCH). A dedicatedLocalTimeconverter family would close that gap for time-of-day fields (DBTIMEcolumns, business hours, schedules) without requiring users to fall back toStringorLocalDateTime.1. Proposed Converter Family (
org.apache.fesod.sheet.converters.localtime)Following the existing
LocalDate/LocalDateTimepattern:LocalTimeDateConverter(Write -> ExcelDATEcell):WriteCellData(value.atDate(DateUtils.EPOCH))with default formatHH:mm:ss.java.sql.TimeinWriteCellData/CsvCell.LocalTimeNumberConverter(Bidirectional ExcelNUMBERserial):DateUtils.getLocalDateTime(serial, use1904windowing).toLocalTime(), so both Excel-native time fractions (0.5=12:00:00) and full datetime serials round-trip to the same wall-clock time.DateUtil.getExcelDate(value.atDate(DateUtils.EPOCH), use1904), consistent with the DATE write path.LocalTimeStringConverter(Bidirectional ExcelSTRINGcell):@DateTimeFormatif present, otherwiseHH:mm:ss(andHH:mmwhen the input has no seconds).Locale.Small
DateUtilsadditions will be needed (mirroringparseLocalDate/format(LocalDate)):defaultLocalTimeFormat = "HH:mm:ss"parseLocalTime(...)/format(LocalTime, ...)HH:mm:ss/HH:mm(currentswitchDateFormatonly covers date/datetime lengths)2. Time-only Semantics
DateUtils.EPOCH(1970-01-01) as the date component, then applyHH:mm:ssso Excel shows time only.toLocalTime(). A numeric cell of0.5and a datetime serial that happens to be12:00:00both becomeLocalTime.of(12, 0, 0).LocalDate(which keeps the date and zeros the time).3. Registration & Test Coverage
LocalTimeNumberConverterandLocalTimeStringConverterinDefaultConverterLoader.initAllConverter().LocalTimeDateConverterandLocalTimeStringConverterinDefaultConverterLoader.initDefaultWriteConverter().LocalTimeConverterTestunderorg.apache.fesod.sheet.converter, covering converter keys, DATE/NUMBER/STRING read-write,@DateTimeFormat,use1904windowing, and the date-dropping behavior.ConverterDataTestwhere appropriate.DefaultConverterLoaderTest.Scope is limited to
java.time.LocalTime(JDK 8).java.sql.Timecan be a follow-up if useful; converter lookup is keyed by the declared Java class, so existingDateconverters do not coverLocalTimefields.If this direction looks good, I’d be happy to take it.
43 remaining items
CodeMan-cmd commentedon Sep 23, 2026
Proposal for three types that are not on the task list yet. I checked the current behaviour on main (4e3f3aa) with a bean per type, and all of them fail on read and on write:
java.sql.Dateis worth calling out separately: it extendsjava.util.Date, which does have converters, but the converter map is keyed by the exact class, so ajava.sql.Datefield gets nothing. It is the sibling ofjava.sql.Timestamp, which is already on the list.Proposal 1 -
java.time.Instant(converters/instant/)InstantDateConverter(Excel DATE): writeDate.from(value)asWriteCellData<Date>; readcellData.getDateValue().toInstant().InstantNumberConverter(Excel NUMBER serial): read and write throughLocalDateTimelike thelocaldatetimefamily, souse1904windowingand the number format keep working;atZone(ZoneId.systemDefault()).toInstant().InstantStringConverter(Excel STRING):DateUtils.format(...)/parseDate(...)with the@DateTimeFormatvalue, falling back to the default pattern.Proposal 2 -
java.sql.Dateandjava.sql.Time(converters/sqldate/,converters/sqltime/)Mirror the existing
converters/date/family one to one (*DateConverter,*NumberConverter,*StringConverter), withtoLocalDate()/toLocalTime()as the intermediate, and register them inDefaultConverterLoader. Same shape as thejava.sql.Timestampproposal that is already assigned, so the sql family stays consistent.Proposal 3 -
java.time.YearMonth(converters/yearmonth/)Excel has no month type, so
YearMonthStringConverterasyyyy-MMplusYearMonthNumberConverterthrough the first day of the month, which keeps sorting and date arithmetic in the sheet working.All three proposals are JDK 8 only, implement
org.apache.fesod.sheet.converters.Converter, and would come with unit tests per converter (write, read and a round trip through xlsx) plus theDefaultConverterLoaderregistration.I will leave this comment for the 24 hours mentioned above and then open the PRs, one type family per PR. If you would rather have them in a different shape (for example
Instantas a string only, orYearMonthas a DATE cell of the first day), tell me and I will adjust before the PR.CodeMan-cmd commentedon Sep 23, 2026
Implemented the three proposals: #1133
converters/sqldate,converters/sqltime,converters/instantandconverters/yearmonth, each with a round trip test over xlsx, xls and csv. They are in one PR because all of them register inDefaultConverterLoaderand separate PRs would conflict there; I can split it if you prefer.Verification on my machine with Temurin 1.8.0_472: 928 tests, 0 failures, and
spotless:checkpasses.BigDataDZ commentedon Oct 8, 2026
I'd like to propose a follow-up batch of four JDK 8 compatible types that are neither on the task list nor proposed yet (verified against
DefaultConverterLoaderand this thread):java.time.Month,java.time.DayOfWeek,java.time.Periodandjava.time.Duration.Proposed approach - one bidirectional STRING converter per type, following the
*StringConverterpattern:MonthStringConverter(converters/month): writesMonth#getDisplayName(TextStyle.FULL, locale)respectingGlobalConfiguration.locale(or a@DateTimeFormatcustom pattern with numericuuuu-MMstyle values also accepted on read); reads case-insensitively viaMonth#valueOfand 1-12 numerically.DayOfWeekStringConverter(converters/dayofweek): same shape as above overDayOfWeek, with 1-7 numeric read support (ISO-8601 Monday=1).PeriodStringConverter(converters/period): writesPeriod#toString()(ISO-8601P1Y2M3D); reads viaPeriod#parse,nullstaysnull.DurationStringConverter(converters/duration): writesDuration#toString()(PT5H30M); reads viaDuration#parse,nullstaysnull.Each ships with JUnit 5 unit tests (round-trip, locale handling where applicable, invalid input reported as
ExcelDataConvertExceptioninstead of being silently coerced) and registration inDefaultConverterLoader. Happy to split them into one PR per type or batch two-and-two, whichever maintainers prefer.feat: add java.time.OffsetDateTime converters (#1017) (#1033)
feat: add Character and Year converters (#1017) (#1087)
Mikkey-f commentedon Oct 12, 2026
I'd like to propose and take the missing number converter for
java.time.Year— the follow-up toYearStringConverter, which landed via #1087 (background discussion in #1216).Current behaviour on main (verified at bf9bf92):
Yearships only the STRING converter, so the(Year, NUMBER)read key is unmapped and a numeric year column fails on read:Date-formatted cells fail the same way, since they are NUMBER cells at read time. The sibling date-like types (
LocalDate,LocalTime,OffsetDateTime,java.util.Date) each ship a number converter, so this closes the gap #1087 left in the family.Proposed converter —
YearNumberConverterunderconverters/year, following the*NumberConverterpattern:2026→Year.of(2026); a serial reading would give 1905, which is not what a year column means);Yearkeeps writing as STRING throughYearStringConverter, unchanged.Implementation is up as #1217, with a unit test plus an end-to-end read test. It was opened earlier today as a bug fix, before the reclassification in #1216 — apologies for skipping the 24-hour notice; happy to hold it if that step should apply.
The plain-number branch is the design point worth a look: if strict family consistency is preferred (always read as a date serial), it can be switched.
feat: add a number converter for java.time.Year (apache#1017)
feat: add UUID string converter (#1017) (#1088)
fix: normalize empty date format and guard invalid dates in Timestamp…
fix: adapt the Timestamp converters to current main (apache#1017)
fix: normalize empty date format and guard invalid dates in Timestamp…
feat: add a number converter for java.time.Year (apache#1017)
fix: adapt the Timestamp converters to current main (apache#1017)
fix: normalize empty date format and guard invalid dates in Timestamp…
feat: add java.sql.Timestamp converters (#1017) (#1220)