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:
Andrew C. Oliver 2002-11-28 19:32:52 +00:00
parent 1e00d428ad
commit b153040a9e
3 changed files with 71 additions and 14 deletions

View File

@ -89,6 +89,7 @@ import org.apache.poi.hssf.util.HSSFColor;
* @author Glen Stampoultzis (glens at apache.org)
* @author Sergei Kozello (sergeikozello at mail.ru)
* @author Luc Girardin (luc dot girardin at macrofocus dot com)
* @author Dan Sherman (dsherman at isisph.com)
* @see org.apache.poi.hssf.usermodel.HSSFWorkbook
* @version 1.0-pre
*/
@ -156,6 +157,8 @@ public class Workbook implements Model {
0; // holds the position of sup book
private short maxformatid =
-1; // holds the max format id
private boolean uses1904datewindowing =
false; // whether 1904 date windowing is being used
private static POILogger log =
POILogFactory.getLogger(Workbook.class);
@ -249,6 +252,10 @@ public class Workbook implements Model {
retval.formats.add(rec);
retval.maxformatid = retval.maxformatid >= ((FormatRecord)rec).getIndexCode() ? retval.maxformatid : ((FormatRecord)rec).getIndexCode();
break;
case DateWindow1904Record.sid :
log.log(DEBUG, "found datewindow1904 record at " + k);
retval.uses1904datewindowing = ((DateWindow1904Record)rec).getWindowing() == 1;
break;
default :
}
@ -1912,4 +1919,14 @@ public class Workbook implements Model {
{
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;
}
}

View File

@ -94,6 +94,7 @@ import java.util.Calendar;
* NOTE: the alpha won't be implementing formulas
*
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Dan Sherman (dsherman at isisph.com)
* @version 1.0-pre
*/
@ -783,7 +784,12 @@ public class HSSFCell
throw new NumberFormatException(
"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);
}
}
/**

View File

@ -69,6 +69,7 @@ import java.util.GregorianCalendar;
*
* @author Michael Harhen
* @author Glen Stampoultzis (glens at apache.org)
* @author Dan Sherman (dsherman at isisph.com)
*/
public class HSSFDateUtil
@ -115,33 +116,54 @@ public class HSSFDateUtil
/**
* Given a excel date, converts it into a Date.
* Assumes 1900 date windowing.
*
* @param date the Excel Date
*
* @return Java representation of a date (null if error)
* @see #getJavaDate(double,boolean)
*/
public static Date getJavaDate(double date)
{
if (isValidExcelDate(date))
{
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);
return getJavaDate(date,false);
}
/**
* 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);
return calendar.getTime();
}
else
{
else {
return null;
}
}
/**
* given a format ID this will check whether the format represents
* an internal date format or not.
@ -164,6 +186,18 @@ public class HSSFDateUtil
case 0x2d:
case 0x2e:
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;
break;