Excel
значения даты в системе дат 1900 начинаются со значения 0 = день 0 в январе 1900 года. До этого значения даты Excel
отсутствуют.
Если у вас есть следующие ячейки в Excel
:
A B
1 Value Excel date
2 0 01/00/1900 00:00:00
3 0.5 01/00/1900 12:00:00
4 1 01/01/1900 00:00:00
5 1.5 01/01/1900 12:00:00
, где значения в столбце B
такие же, как в столбце A
, но отформатированы как даты в числовом формате MM/DD/YYYY hh:mm:ss
, вы видите это.
Таким образом, нет Excel
даты 31 декабря 1899 года. Вот почему DateUtil.getExcelDate(date)
терпит неудачу, когда date
является Java
датой Sun Dec 31 00:00:00 GMT 1899
или Sun Dec 31 12:00:00 GMT 1899
.
Но DateUtil.getJavaDate(excelDate)
возвращает 31 декабря 1899 года, когда excelDate
является значением double
от 0.0
до 0.999...
. Это потому, что Java
дата января 0 1900 невозможна. Но возможны Excel
значения даты от 0.0
до 0.999...
.
Другими словами, Excel
значения даты от 0.0
до 0.999...
в действительности являются значениями времени до первого возможного целого дня в Excel
, который является датой 01 января 1900 года. Они на самом деле не в дне, а вместо этого в дне 0.
Поскольку значения даты от 0.0
до 0.999...
и преобразованные Java
даты 31 декабря 1899 г. являются особыми случаями, и их можно обрабатывать как таковые.
Расширяя код:
import java.util.Date;
import java.util.Calendar;
import java.util.stream.DoubleStream;
import org.apache.poi.ss.usermodel.DateUtil;
public class POIQuery {
public static void main(final String[] args) {
final String format = "%-20s%-35s%-20s%n"; //$NON-NLS-1$
System.out.format(format, "Input Excel Date", "Java Date", "Converted Excel Date");
DoubleStream.of(0, 0.5d, 1d, 1.5d, 44000d, 44000.5d).forEach(excelDate -> {
final Date date = DateUtil.getJavaDate(excelDate);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
double excelDateFromDate = -1d;
if (cal.get(Calendar.YEAR) == 1899 && cal.get(Calendar.MONTH) == 11 && cal.get(Calendar.DATE) == 31) {
cal.add(Calendar.DATE, 1);
excelDateFromDate = DateUtil.getExcelDate(cal.getTime());
excelDateFromDate -= 1d;
} else {
excelDateFromDate = DateUtil.getExcelDate(date);
}
System.out.format(format, excelDate, date, excelDateFromDate);
});
}
}
Если преобразованная дата Java
это 31 декабря 1899 года, и мы знаем, что это значение было преобразовано из Excel
, затем при преобразовании его в Excel
значение даты сначала добавьте за один день до использования DateUtil.getExcelDate
. Так что DateUtil.getExcelDate
конвертируется с 01 января 1900 года. Затем вычтите 1
из результата DateUtil.getExcelDate
.