[英]Converting ArrayList<Double> to Double Array and vice-versa for JAVA/Android
[英]POI - Problems converting between Excel & Java date & vice-versa
我正在嘗試使用 Apache POI (4.0.1) 在 Excel 工作簿的單元格中節省時間。
我將時間轉換為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));
});
}
}
輸出(請注意,根據文檔 - “-1”的“轉換后的 Excel 日期”表示錯誤)。
Input Excel Date Java Date Converted Excel Date
0.0 Sun Dec 31 00:00:00 GMT 1899 -1.0
0.5 Sun Dec 31 12:00:00 GMT 1899 -1.0
1.5 Mon Jan 01 12:00:00 GMT 1900 1.5
在這里您可以看到我要求表示 Excel 日期“0.5”的 Java 日期。 然后我使用提供的 Java 日期,但 POI 說沒有與該日期相對應的 Excel 日期 - 即使我已經從中生成了它。
我是不是錯過了什么……?
1900 年日期系統中的Excel
日期值從值 0 = 1900 年 1 月的第 0 天開始。在此之前沒有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
日期 1899 年 12 月 31 日。這就是為什么DateUtil.getExcelDate(date)
在date
是Java
日期Sun Dec 31 00:00:00 GMT 1899
或Sun Dec 31 12:00:00 GMT 1899
時失敗的原因。
但是DateUtil.getJavaDate(excelDate)
返回 1899 年 12 月 31 日,當excelDate
是從0.0
到0.999...
的double
DateUtil.getJavaDate(excelDate)
值時。 那是因為沒有可能的Java
日期 1900 年 1 月 0 日。 但是Excel
日期值可能從0.0
到0.999...
。
換句話說, Excel
日期值從0.0
到0.999...
實際上是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
轉換。然后從DateUtil.getExcelDate
的結果中減去1
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.