Java POI-Excel和;爪哇日期及日期;反之亦然
我正在尝试使用ApachePOI(4.0.1)在Excel工作簿的单元格中节省时间 我将时间转换为Java POI-Excel和;爪哇日期及日期;反之亦然,java,excel,apache-poi,Java,Excel,Apache Poi,我正在尝试使用ApachePOI(4.0.1)在Excel工作簿的单元格中节省时间 我将时间转换为java.util.Date,然后尝试使用org.apache.poi.ss.usermodel.DateUtil.getExcelDate方法将其保存在单元格中 我的发现是,由于时间与纪元(1899年)在同一年,因此在getExcelDate中有一个硬编码的签入,该签入禁止将日期转换为1900年之前的年份,从而阻止我做我要做的事情 示例应用程序: import java.util.Date; im
java.util.Date
,然后尝试使用org.apache.poi.ss.usermodel.DateUtil.getExcelDate
方法将其保存在单元格中
我的发现是,由于时间与纪元(1899年)在同一年,因此在getExcelDate
中有一个硬编码的签入,该签入禁止将日期转换为1900年之前的年份,从而阻止我做我要做的事情
示例应用程序:
import java.util.Date;
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, 1.5d).forEach(excelDate -> {
final Date date = DateUtil.getJavaDate(excelDate);
System.out.format(format, excelDate, date, DateUtil.getExcelDate(date));
});
}
}
输出(注意,根据文档-转换的Excel日期“-1”表示错误)
在这里您可以看到,我要求的是表示Excel日期“0.5”的Java日期。
然后我使用提供的Java日期,但是POI说没有与之对应的Excel日期——尽管我是根据该日期生成的
我是否遗漏了什么…?
Excel
1900年日期系统中的日期值从值0=1900年1月的第0天开始。在此之前没有Excel
date值
如果在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/yyyyy hh:MM:ss
格式化为日期,则可以看到
因此,没有日期为1899年12月31日的Excel
。这就是为什么DateUtil.getExcelDate(date)
在date
是Java
dateSun Dec 31 00:00 GMT 1899
或Sun Dec 31 12:00 GMT 1899
时失败的原因
但是DateUtil.getJavaDate(excelDate)
返回1899年12月31日,此时excelDate
是0.0
到0.999之间的double
值…
。这是因为没有Java
1900年1月0日的日期。但是有Excel
日期值可以从0.0
到0.999…
换句话说,从0.0
到0.999…
的Excel
日期值实际上是在Excel
中第一个可能的全天之前的时间值,即1900年1月1日。它们不是在一天之内,而是在第0天
由于从0.0
到0.999…
的日期值以及转换为Java
的1899年12月31日的日期都是特殊情况,因此可以这样处理它们
通过扩展代码:
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
日期是1899年12月31日,并且我们知道这是从Excel
转换而来的,那么在将其重新转换为Excel
日期值时,首先在使用DateUtil.getExcelDate
之前添加一天。因此DateUtil.getExcelDate
从1900年1月1日开始转换。然后从DateUtil.getExcelDate
的结果中减去1
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);
});
}
}