mirror of https://github.com/apache/poi.git
PR: Obtained from: Submitted by: Reviewed by: git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352931 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
0c5f8a6bf4
commit
27a7b12c20
|
@ -89,6 +89,7 @@ import org.apache.poi.hssf.util.HSSFColor;
|
||||||
* @author Glen Stampoultzis (glens at apache.org)
|
* @author Glen Stampoultzis (glens at apache.org)
|
||||||
* @author Sergei Kozello (sergeikozello at mail.ru)
|
* @author Sergei Kozello (sergeikozello at mail.ru)
|
||||||
* @author Luc Girardin (luc dot girardin at macrofocus dot com)
|
* @author Luc Girardin (luc dot girardin at macrofocus dot com)
|
||||||
|
* @author Dan Sherman (dsherman at isisph.com)
|
||||||
* @see org.apache.poi.hssf.usermodel.HSSFWorkbook
|
* @see org.apache.poi.hssf.usermodel.HSSFWorkbook
|
||||||
* @version 1.0-pre
|
* @version 1.0-pre
|
||||||
*/
|
*/
|
||||||
|
@ -156,6 +157,8 @@ public class Workbook implements Model {
|
||||||
0; // holds the position of sup book
|
0; // holds the position of sup book
|
||||||
private short maxformatid =
|
private short maxformatid =
|
||||||
-1; // holds the max format id
|
-1; // holds the max format id
|
||||||
|
private boolean uses1904datewindowing =
|
||||||
|
false; // whether 1904 date windowing is being used
|
||||||
|
|
||||||
private static POILogger log =
|
private static POILogger log =
|
||||||
POILogFactory.getLogger(Workbook.class);
|
POILogFactory.getLogger(Workbook.class);
|
||||||
|
@ -249,6 +252,10 @@ public class Workbook implements Model {
|
||||||
retval.formats.add(rec);
|
retval.formats.add(rec);
|
||||||
retval.maxformatid = retval.maxformatid >= ((FormatRecord)rec).getIndexCode() ? retval.maxformatid : ((FormatRecord)rec).getIndexCode();
|
retval.maxformatid = retval.maxformatid >= ((FormatRecord)rec).getIndexCode() ? retval.maxformatid : ((FormatRecord)rec).getIndexCode();
|
||||||
break;
|
break;
|
||||||
|
case DateWindow1904Record.sid :
|
||||||
|
log.log(DEBUG, "found datewindow1904 record at " + k);
|
||||||
|
retval.uses1904datewindowing = ((DateWindow1904Record)rec).getWindowing() == 1;
|
||||||
|
break;
|
||||||
|
|
||||||
default :
|
default :
|
||||||
}
|
}
|
||||||
|
@ -1912,4 +1919,14 @@ public class Workbook implements Model {
|
||||||
{
|
{
|
||||||
return records;
|
return records;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether date windowing is based on 1/2/1904 or 1/1/1900.
|
||||||
|
* Some versions of Excel (Mac) can save workbooks using 1904 date windowing.
|
||||||
|
*
|
||||||
|
* @return true if using 1904 date windowing
|
||||||
|
*/
|
||||||
|
public boolean isUsing1904DateWindowing() {
|
||||||
|
return uses1904datewindowing;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,7 @@ import java.util.Calendar;
|
||||||
* NOTE: the alpha won't be implementing formulas
|
* NOTE: the alpha won't be implementing formulas
|
||||||
*
|
*
|
||||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||||
|
* @author Dan Sherman (dsherman at isisph.com)
|
||||||
* @version 1.0-pre
|
* @version 1.0-pre
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -783,7 +784,12 @@ public class HSSFCell
|
||||||
throw new NumberFormatException(
|
throw new NumberFormatException(
|
||||||
"You cannot get a date value from an error cell");
|
"You cannot get a date value from an error cell");
|
||||||
}
|
}
|
||||||
return HSSFDateUtil.getJavaDate(cellValue);
|
if (book.isUsing1904DateWindowing()) {
|
||||||
|
return HSSFDateUtil.getJavaDate(cellValue,true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return HSSFDateUtil.getJavaDate(cellValue,false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -69,6 +69,7 @@ import java.util.GregorianCalendar;
|
||||||
*
|
*
|
||||||
* @author Michael Harhen
|
* @author Michael Harhen
|
||||||
* @author Glen Stampoultzis (glens at apache.org)
|
* @author Glen Stampoultzis (glens at apache.org)
|
||||||
|
* @author Dan Sherman (dsherman at isisph.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class HSSFDateUtil
|
public class HSSFDateUtil
|
||||||
|
@ -115,29 +116,50 @@ public class HSSFDateUtil
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a excel date, converts it into a Date.
|
* Given a excel date, converts it into a Date.
|
||||||
|
* Assumes 1900 date windowing.
|
||||||
*
|
*
|
||||||
* @param date the Excel Date
|
* @param date the Excel Date
|
||||||
*
|
*
|
||||||
* @return Java representation of a date (null if error)
|
* @return Java representation of a date (null if error)
|
||||||
|
* @see #getJavaDate(double,boolean)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static Date getJavaDate(double date)
|
public static Date getJavaDate(double date)
|
||||||
{
|
{
|
||||||
if (isValidExcelDate(date))
|
return getJavaDate(date,false);
|
||||||
{
|
}
|
||||||
int wholeDaysSince1900 = ( int ) Math.floor(date);
|
|
||||||
GregorianCalendar calendar = new GregorianCalendar(1900,
|
|
||||||
0, wholeDaysSince1900
|
|
||||||
- 1);
|
|
||||||
int millisecondsInDay =
|
|
||||||
( int ) ((date - Math.floor(date))
|
|
||||||
* ( double ) DAY_MILLISECONDS + 0.5);
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an Excel date with either 1900 or 1904 date windowing,
|
||||||
|
* converts it to a java.util.Date.
|
||||||
|
*
|
||||||
|
* @param date The Excel date.
|
||||||
|
* @param use1904windowing true if date uses 1904 windowing,
|
||||||
|
* or false if using 1900 date windowing.
|
||||||
|
* @return Java representation of the date, or null if date is not a valid Excel date
|
||||||
|
*/
|
||||||
|
public static Date getJavaDate(double date, boolean use1904windowing) {
|
||||||
|
if (isValidExcelDate(date)) {
|
||||||
|
int startYear = 1900;
|
||||||
|
int dayAdjust = -1; // Excel thinks 2/29/1900 is a valid date, which it isn't
|
||||||
|
int wholeDays = (int)Math.floor(date);
|
||||||
|
if (use1904windowing) {
|
||||||
|
startYear = 1904;
|
||||||
|
dayAdjust = 1; // 1904 date windowing uses 1/2/1904 as the first day
|
||||||
|
}
|
||||||
|
else if (wholeDays < 61) {
|
||||||
|
// Date is prior to 3/1/1900, so adjust because Excel thinks 2/29/1900 exists
|
||||||
|
// If Excel date == 2/29/1900, will become 3/1/1900 in Java representation
|
||||||
|
dayAdjust = 0;
|
||||||
|
}
|
||||||
|
GregorianCalendar calendar = new GregorianCalendar(startYear,0,
|
||||||
|
wholeDays + dayAdjust);
|
||||||
|
int millisecondsInDay = (int)((date - Math.floor(date)) *
|
||||||
|
(double) DAY_MILLISECONDS + 0.5);
|
||||||
calendar.set(GregorianCalendar.MILLISECOND, millisecondsInDay);
|
calendar.set(GregorianCalendar.MILLISECOND, millisecondsInDay);
|
||||||
return calendar.getTime();
|
return calendar.getTime();
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,6 +186,18 @@ public class HSSFDateUtil
|
||||||
case 0x2d:
|
case 0x2d:
|
||||||
case 0x2e:
|
case 0x2e:
|
||||||
case 0x2f:
|
case 0x2f:
|
||||||
|
// Additional internal date formats found by inspection
|
||||||
|
// Using Excel v.X 10.1.0 (Mac)
|
||||||
|
case 0xa4:
|
||||||
|
case 0xa5:
|
||||||
|
case 0xa6:
|
||||||
|
case 0xa7:
|
||||||
|
case 0xa8:
|
||||||
|
case 0xa9:
|
||||||
|
case 0xaa:
|
||||||
|
case 0xab:
|
||||||
|
case 0xac:
|
||||||
|
case 0xad:
|
||||||
retval = true;
|
retval = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue