久々に JavaでExcel を読込む apache POI を使う。
try(InputStream is = new FileInputStream("sample.xlsx"); XSSFWorkbook book = new XSSFWorkbook(is)){ XSSFSheet sheet = book.getSheetAt(0); XSSFRow row = sheet.getRow(2); XSSFCell cell = row.getCell(1);
org.apache.poi.ss.usermodel.CellType は、NUMERIC であり、getNumericCellValue() で値を参照する必要がある。
参照する型は、double である。
だから、
cell.getNumericCellValue()
は、double であり、しかも、Excel の EPOCH 基準日は特殊である。
これを java.util.Date に変換するものが、
apache POI には用意されている。
org.apache.poi.ss.usermodel.DateUtil
の
getJavaDate(double date)
が、 java.util.Date を返す。
でも、 java.util.Date なんかもう使わないので、 java.time.LocalDate にする。
Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(cell.getNumericCellValue()); LocalDate loaldate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
Excel の EPOCH 基準日が特殊というのは、
(UTC)Unix Epoch Time 1970 年 1月1日 0時0分0秒からを基準ではなく、
1900年 1月1日 0時0分0秒 を Excel が基準にしていることだ。
だから、org.apache.poi.ss.usermodel.DateUtil で
変換メソッドが提供されている。
stackoverflow に以下の記事があるが、、
https://stackoverflow.com/questions/19028192/converting-number-representation-of-date-in-excel-to-date-in-java
確かに
1900年1月1日より後ろの日付では、
LocalDate.of(1899, 12, 30).plusDays((long)cell.getNumericCellValue())
という計算もできるであろうが、1900年 1月1日である double 値 1.0 に対しては使えない。
1899-12-31
になってしまう。