Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,13 @@ protected void setCellValueImpl(Date value) {
if (value == null) {
return;
}
this.dateValue = LocalDateTime.ofInstant(value.toInstant(), ZoneId.systemDefault());
if (value instanceof java.sql.Date) {
this.dateValue = ((java.sql.Date) value).toLocalDate().atStartOfDay();
} else if (value instanceof java.sql.Time) {
this.dateValue = ((java.sql.Time) value).toLocalTime().atDate(java.time.LocalDate.of(1970, 1, 1));
} else {
this.dateValue = LocalDateTime.ofInstant(value.toInstant(), ZoneId.systemDefault());
}
this.cellType = CellType.NUMERIC;
this.numericCellType = NumericCellTypeEnum.DATE;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,15 @@
package org.apache.fesod.sheet.format;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import org.apache.fesod.sheet.FastExcel;
import org.apache.fesod.sheet.metadata.csv.CsvCell;
import org.apache.fesod.sheet.metadata.csv.CsvRow;
import org.apache.fesod.sheet.metadata.csv.CsvSheet;
import org.apache.fesod.sheet.metadata.csv.CsvWorkbook;
Expand Down Expand Up @@ -120,6 +125,88 @@ void testCsvWriteWithModelShouldSuccess() {
.doWrite(modelData());
}

/**
* Verifies that {@link CsvCell} handles {@link java.sql.Date} the same way as
* {@link org.apache.fesod.sheet.metadata.data.WriteCellData}: the date is extracted
* via {@code toLocalDate().atStartOfDay()}, stripping any time component that may
* exist in the underlying milliseconds (common when JDBC drivers create
* {@code java.sql.Date} from a {@code java.util.Date} with time info).
*/
@Test
void testCsvCellSqlDateConversion() {
// Create a java.sql.Date from a java.util.Date that has a time component
Calendar cal = Calendar.getInstance();
cal.set(2023, Calendar.JUNE, 15, 23, 30, 0);
cal.set(Calendar.MILLISECOND, 0);
java.sql.Date sqlDate = new java.sql.Date(cal.getTimeInMillis());

Cell cell = csvRow.createCell(0, CellType.NUMERIC);
cell.setCellValue(sqlDate);

LocalDateTime dateValue = ((CsvCell) cell).getLocalDateTimeCellValue();
// java.sql.Date is date-only: time component must be stripped to midnight
Assertions.assertEquals(LocalDateTime.of(2023, 6, 15, 0, 0, 0), dateValue);
Comment thread
alaahong marked this conversation as resolved.
}

/**
* Verifies that {@link CsvCell} handles {@link java.sql.Time} the same way as
* {@link org.apache.fesod.sheet.metadata.data.WriteCellData}: the time is extracted
* via {@code toLocalTime().atDate(LocalDate.of(1970, 1, 1))}, stripping any date
* component that may exist in the underlying milliseconds.
*/
@Test
void testCsvCellSqlTimeConversion() {
// Create a java.sql.Time from a java.util.Date that has a date component
Calendar cal = Calendar.getInstance();
cal.set(2023, Calendar.JUNE, 15, 12, 30, 45);
cal.set(Calendar.MILLISECOND, 0);
java.sql.Time sqlTime = new java.sql.Time(cal.getTimeInMillis());

Cell cell = csvRow.createCell(0, CellType.NUMERIC);
cell.setCellValue(sqlTime);

LocalDateTime dateValue = ((CsvCell) cell).getLocalDateTimeCellValue();
// java.sql.Time is time-only: date component must be normalized to 1970-01-01
Assertions.assertEquals(LocalDateTime.of(1970, 1, 1, 12, 30, 45), dateValue);
Comment thread
alaahong marked this conversation as resolved.
}

/**
* Real-file integration test: writes a physical CSV file containing
* {@code java.sql.Date} and {@code java.sql.Time} values via the
* {@link CsvCell} API, then reads the file back to verify the output.
* <p>
* Without the fix, {@code CsvCell.setCellValueImpl(Date)} calls
* {@code value.toInstant()} which throws {@code UnsupportedOperationException}
* on Java 9+ for {@code java.sql.Date}/{@code java.sql.Time}.
*/
@Test
void csvWrite_withSqlDateAndTime_producesCorrectFile() throws Exception {
File csvFile = new File(tempDir, "sql-date-test.csv");

try (java.io.Writer writer = Files.newBufferedWriter(csvFile.toPath(), StandardCharsets.UTF_8)) {
CsvWorkbook workbook = new CsvWorkbook(writer, null, false, false, StandardCharsets.UTF_8, false);
CsvSheet sheet = (CsvSheet) workbook.createSheet();
CsvRow row = (CsvRow) sheet.createRow(0);

// java.sql.Date — without fix: UnsupportedOperationException
Cell dateCell = row.createCell(0, CellType.NUMERIC);
dateCell.setCellValue(java.sql.Date.valueOf("2024-01-15"));

// java.sql.Time — without fix: UnsupportedOperationException
Cell timeCell = row.createCell(1, CellType.NUMERIC);
timeCell.setCellValue(java.sql.Time.valueOf("12:30:45"));

sheet.close();
}

// Read file back and verify date/time strings
List<String> lines = Files.readAllLines(csvFile.toPath(), StandardCharsets.UTF_8);
Assertions.assertEquals(1, lines.size());
String line = lines.get(0);
Assertions.assertTrue(line.contains("2024-01-15"), "CSV should contain date 2024-01-15, got: " + line);
Assertions.assertTrue(line.contains("12:30:45"), "CSV should contain time 12:30:45, got: " + line);
}

private static List<SimpleCsvData> modelData() {
List<SimpleCsvData> data = new ArrayList<>();
data.add(new SimpleCsvData("1", "Jackson", "20"));
Expand Down
Loading