git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@601004 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_0_3_BETA1
@@ -36,6 +36,7 @@ | |||
<!-- Don't forget to update status.xml too! --> | |||
<release version="3.0.2-FINAL" date="2007-??-??"> | |||
<action dev="POI-DEVELOPERS" type="add">43551 - [PATCH] Support for 1904 date windowing in HSSF (previously only supported 1900 date windowing)</action> | |||
<action dev="POI-DEVELOPERS" type="add">41064 - [PATCH] Support for String continue records</action> | |||
<action dev="POI-DEVELOPERS" type="add">27511 - [PATCH] Support for data validation, via DVRecord and DVALRecord</action> | |||
<action dev="POI-DEVELOPERS" type="fix">43877 and 39512 - Fix for handling mixed OBJ and CONTINUE records.</action> |
@@ -33,6 +33,7 @@ | |||
<!-- Don't forget to update changes.xml too! --> | |||
<changes> | |||
<release version="3.0.2-FINAL" date="2007-??-??"> | |||
<action dev="POI-DEVELOPERS" type="add">43551 - [PATCH] Support for 1904 date windowing in HSSF (previously only supported 1900 date windowing)</action> | |||
<action dev="POI-DEVELOPERS" type="add">41064 - [PATCH] Support for String continue records</action> | |||
<action dev="POI-DEVELOPERS" type="add">27511 - [PATCH] Support for data validation, via DVRecord and DVALRecord</action> | |||
<action dev="POI-DEVELOPERS" type="fix">43877 - Fix for handling mixed OBJ and CONTINUE records</action> |
@@ -521,7 +521,7 @@ public class HSSFCell | |||
*/ | |||
public void setCellValue(Date value) | |||
{ | |||
setCellValue(HSSFDateUtil.getExcelDate(value)); | |||
setCellValue(HSSFDateUtil.getExcelDate(value, this.book.isUsing1904DateWindowing())); | |||
} | |||
/** |
@@ -35,6 +35,8 @@ import java.util.GregorianCalendar; | |||
* @author Glen Stampoultzis (glens at apache.org) | |||
* @author Dan Sherman (dsherman at isisph.com) | |||
* @author Hack Kampbjorn (hak at 2mba.dk) | |||
* @author Alex Jacoby (ajacoby at gmail.com) | |||
* @author Pavel Krupets (pkrupets at palmtreebusiness dot com) | |||
*/ | |||
public class HSSFDateUtil | |||
@@ -54,19 +56,26 @@ public class HSSFDateUtil | |||
* @return Excel representation of Date (-1 if error - test for error by checking for less than 0.1) | |||
* @param date the Date | |||
*/ | |||
public static double getExcelDate(Date date) | |||
{ | |||
public static double getExcelDate(Date date) { | |||
return getExcelDate(date, false); | |||
} | |||
/** | |||
* Given a Date, converts it into a double representing its internal Excel representation, | |||
* which is the number of days since 1/1/1900. Fractional days represent hours, minutes, and seconds. | |||
* | |||
* @return Excel representation of Date (-1 if error - test for error by checking for less than 0.1) | |||
* @param date the Date | |||
* @param use1904windowing Should 1900 or 1904 date windowing be used? | |||
*/ | |||
public static double getExcelDate(Date date, boolean use1904windowing) { | |||
Calendar calStart = new GregorianCalendar(); | |||
calStart.setTime( | |||
date); // If date includes hours, minutes, and seconds, set them to 0 | |||
if (calStart.get(Calendar.YEAR) < 1900) | |||
calStart.setTime(date); // If date includes hours, minutes, and seconds, set them to 0 | |||
if ((!use1904windowing && calStart.get(Calendar.YEAR) < 1900) || | |||
(use1904windowing && calStart.get(Calendar.YEAR) < 1904)) | |||
{ | |||
return BAD_DATE; | |||
} | |||
else | |||
{ | |||
} else { | |||
// Because of daylight time saving we cannot use | |||
// date.getTime() - calStart.getTimeInMillis() | |||
// as the difference in milliseconds between 00:00 and 04:00 | |||
@@ -80,32 +89,39 @@ public class HSSFDateUtil | |||
) * 1000 + calStart.get(Calendar.MILLISECOND) | |||
) / ( double ) DAY_MILLISECONDS; | |||
calStart = dayStart(calStart); | |||
double value = fraction + absoluteDay(calStart); | |||
if (value >= 60) { | |||
value += 1; | |||
double value = fraction + absoluteDay(calStart, use1904windowing); | |||
if (!use1904windowing && value >= 60) { | |||
value++; | |||
} else if (use1904windowing) { | |||
value--; | |||
} | |||
return value; | |||
} | |||
} | |||
/** | |||
* Given a excel date, converts it into a Date. | |||
* Assumes 1900 date windowing. | |||
* Given an Excel date with using 1900 date windowing, and | |||
* converts it to a java.util.Date. | |||
* | |||
* @param date the Excel Date | |||
* | |||
* @return Java representation of a date (null if error) | |||
* @see #getJavaDate(double,boolean) | |||
* NOTE: If the default <code>TimeZone</code> in Java uses Daylight | |||
* Saving Time then the conversion back to an Excel date may not give | |||
* the same value, that is the comparison | |||
* <CODE>excelDate == getExcelDate(getJavaDate(excelDate,false))</CODE> | |||
* is not always true. For example if default timezone is | |||
* <code>Europe/Copenhagen</code>, on 2004-03-28 the minute after | |||
* 01:59 CET is 03:00 CEST, if the excel date represents a time between | |||
* 02:00 and 03:00 then it is converted to past 03:00 summer time | |||
* | |||
* @param date The Excel date. | |||
* @return Java representation of the date, or null if date is not a valid Excel date | |||
* @see java.util.TimeZone | |||
*/ | |||
public static Date getJavaDate(double date) | |||
{ | |||
return getJavaDate(date,false); | |||
public static Date getJavaDate(double date) { | |||
return getJavaDate(date, false); | |||
} | |||
/** | |||
* Given an Excel date with either 1900 or 1904 date windowing, | |||
* converts it to a java.util.Date. | |||
@@ -142,7 +158,7 @@ public class HSSFDateUtil | |||
GregorianCalendar calendar = new GregorianCalendar(startYear,0, | |||
wholeDays + dayAdjust); | |||
int millisecondsInDay = (int)((date - Math.floor(date)) * | |||
(double) DAY_MILLISECONDS + 0.5); | |||
DAY_MILLISECONDS + 0.5); | |||
calendar.set(GregorianCalendar.MILLISECOND, millisecondsInDay); | |||
return calendar.getTime(); | |||
} | |||
@@ -238,7 +254,7 @@ public class HSSFDateUtil | |||
* Check if a cell contains a date | |||
* Since dates are stored internally in Excel as double values | |||
* we infer it is a date if it is formatted as such. | |||
* @see #isADateFormat(int,string) | |||
* @see #isADateFormat(int, String) | |||
* @see #isInternalDateFormat(int) | |||
*/ | |||
public static boolean isCellDateFormatted(HSSFCell cell) { | |||
@@ -259,7 +275,7 @@ public class HSSFDateUtil | |||
* excel date formats. | |||
* As Excel stores a great many of its dates in "non-internal" | |||
* date formats, you will not normally want to use this method. | |||
* @see #isADateFormat(int,string) | |||
* @see #isADateFormat(int,String) | |||
* @see #isInternalDateFormat(int) | |||
*/ | |||
public static boolean isCellInternalDateFormatted(HSSFCell cell) { | |||
@@ -296,10 +312,10 @@ public class HSSFDateUtil | |||
* @exception IllegalArgumentException if date is invalid | |||
*/ | |||
private static int absoluteDay(Calendar cal) | |||
static int absoluteDay(Calendar cal, boolean use1904windowing) | |||
{ | |||
return cal.get(Calendar.DAY_OF_YEAR) | |||
+ daysInPriorYears(cal.get(Calendar.YEAR)); | |||
+ daysInPriorYears(cal.get(Calendar.YEAR), use1904windowing); | |||
} | |||
/** | |||
@@ -307,14 +323,14 @@ public class HSSFDateUtil | |||
* | |||
* @return days number of days in years prior to yr. | |||
* @param yr a year (1900 < yr < 4000) | |||
* @param use1904windowing | |||
* @exception IllegalArgumentException if year is outside of range. | |||
*/ | |||
private static int daysInPriorYears(int yr) | |||
private static int daysInPriorYears(int yr, boolean use1904windowing) | |||
{ | |||
if (yr < 1900) { | |||
throw new IllegalArgumentException( | |||
"'year' must be 1900 or greater"); | |||
if ((!use1904windowing && yr < 1900) || (use1904windowing && yr < 1900)) { | |||
throw new IllegalArgumentException("'year' must be 1900 or greater"); | |||
} | |||
int yr1 = yr - 1; | |||
@@ -323,7 +339,7 @@ public class HSSFDateUtil | |||
+ yr1 / 400 // plus years divisible by 400 | |||
- 460; // leap days in previous 1900 years | |||
return 365 * (yr - 1900) + leapDays; | |||
return 365 * (yr - (use1904windowing ? 1904 : 1900)) + leapDays; | |||
} | |||
// set HH:MM:SS fields of cal to 00:00:00:000 |
@@ -283,7 +283,7 @@ public class XLS2CSVmra implements HSSFListener { | |||
format = format.replaceAll("\\\\-","-"); | |||
// Format as a date | |||
Date d = HSSFDateUtil.getJavaDate(value); | |||
Date d = HSSFDateUtil.getJavaDate(value, false); | |||
DateFormat df = new SimpleDateFormat(format); | |||
return df.format(d); | |||
} else { |
@@ -70,7 +70,7 @@ public class Date extends NumericFunction { | |||
c.set(year, month, day, 0, 0, 0); | |||
c.set(Calendar.MILLISECOND, 0); | |||
return new NumberEval(HSSFDateUtil.getExcelDate(c.getTime())); | |||
return new NumberEval(HSSFDateUtil.getExcelDate(c.getTime(), false)); // XXX fix 1900/1904 problem | |||
} | |||
} | |||
@@ -46,7 +46,7 @@ srcCellRow, srcCellCol); | |||
if (ve instanceof NumericValueEval) { | |||
NumericValueEval ne = (NumericValueEval) ve; | |||
if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) { | |||
java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue()); | |||
java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem | |||
java.util.Calendar c = java.util.Calendar.getInstance(); | |||
c.setTime(d); | |||
retval = new NumberEval(c.get(java.util.Calendar.DAY_OF_MONTH)); |
@@ -50,7 +50,7 @@ public class Month extends NumericFunction { | |||
if (ve instanceof NumericValueEval) { | |||
NumericValueEval ne = (NumericValueEval) ve; | |||
if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) { | |||
java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue()); | |||
java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem | |||
retval = new NumberEval(d.getMonth()+1); | |||
} else { | |||
retval = ErrorEval.NUM_ERROR; |
@@ -51,7 +51,7 @@ public class Year extends NumericFunction { | |||
if (ve instanceof NumericValueEval) { | |||
NumericValueEval ne = (NumericValueEval) ve; | |||
if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) { | |||
java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue()); | |||
java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem | |||
retval = new NumberEval(d.getYear()+1900); | |||
} else { | |||
retval = ErrorEval.NUM_ERROR; |
@@ -44,6 +44,7 @@ import java.util.GregorianCalendar; | |||
* paticular datatypes, etc. | |||
* @author Andrew C. Oliver (andy at superlinksoftware dot com) | |||
* @author Dan Sherman (dsherman at isisph.com) | |||
* @author Alex Jacoby (ajacoby at gmail.com) | |||
*/ | |||
public class TestHSSFCell | |||
@@ -107,42 +108,106 @@ extends TestCase { | |||
} | |||
/** | |||
* Checks that the recognition of files using 1904 date windowing | |||
* is working properly. Conversion of the date is also an issue, | |||
* but there's a separate unit test for that. | |||
*/ | |||
public void testDateWindowing() throws Exception { | |||
GregorianCalendar cal = new GregorianCalendar(2000,0,1); // Jan. 1, 2000 | |||
Date date = cal.getTime(); | |||
String path = System.getProperty("HSSF.testdata.path"); | |||
// first check a file with 1900 Date Windowing | |||
String filename = path + "/1900DateWindowing.xls"; | |||
FileInputStream stream = new FileInputStream(filename); | |||
POIFSFileSystem fs = new POIFSFileSystem(stream); | |||
HSSFWorkbook workbook = new HSSFWorkbook(fs); | |||
HSSFSheet sheet = workbook.getSheetAt(0); | |||
assertEquals("Date from file using 1900 Date Windowing", | |||
date.getTime(), | |||
sheet.getRow(0).getCell((short)0) | |||
.getDateCellValue().getTime()); | |||
stream.close(); | |||
// now check a file with 1904 Date Windowing | |||
filename = path + "/1904DateWindowing.xls"; | |||
stream = new FileInputStream(filename); | |||
fs = new POIFSFileSystem(stream); | |||
workbook = new HSSFWorkbook(fs); | |||
sheet = workbook.getSheetAt(0); | |||
assertEquals("Date from file using 1904 Date Windowing", | |||
date.getTime(), | |||
sheet.getRow(0).getCell((short)0) | |||
.getDateCellValue().getTime()); | |||
stream.close(); | |||
} | |||
* Checks that the recognition of files using 1904 date windowing | |||
* is working properly. Conversion of the date is also an issue, | |||
* but there's a separate unit test for that. | |||
*/ | |||
public void testDateWindowingRead() throws Exception { | |||
GregorianCalendar cal = new GregorianCalendar(2000,0,1); // Jan. 1, 2000 | |||
Date date = cal.getTime(); | |||
String path = System.getProperty("HSSF.testdata.path"); | |||
// first check a file with 1900 Date Windowing | |||
String filename = path + "/1900DateWindowing.xls"; | |||
FileInputStream stream = new FileInputStream(filename); | |||
POIFSFileSystem fs = new POIFSFileSystem(stream); | |||
HSSFWorkbook workbook = new HSSFWorkbook(fs); | |||
HSSFSheet sheet = workbook.getSheetAt(0); | |||
assertEquals("Date from file using 1900 Date Windowing", | |||
date.getTime(), | |||
sheet.getRow(0).getCell((short)0) | |||
.getDateCellValue().getTime()); | |||
stream.close(); | |||
// now check a file with 1904 Date Windowing | |||
filename = path + "/1904DateWindowing.xls"; | |||
stream = new FileInputStream(filename); | |||
fs = new POIFSFileSystem(stream); | |||
workbook = new HSSFWorkbook(fs); | |||
sheet = workbook.getSheetAt(0); | |||
assertEquals("Date from file using 1904 Date Windowing", | |||
date.getTime(), | |||
sheet.getRow(0).getCell((short)0) | |||
.getDateCellValue().getTime()); | |||
stream.close(); | |||
} | |||
/** | |||
* Checks that dates are properly written to both types of files: | |||
* those with 1900 and 1904 date windowing. Note that if the | |||
* previous test ({@link #testDateWindowingRead}) fails, the | |||
* results of this test are meaningless. | |||
*/ | |||
public void testDateWindowingWrite() throws Exception { | |||
GregorianCalendar cal = new GregorianCalendar(2000,0,1); // Jan. 1, 2000 | |||
Date date = cal.getTime(); | |||
String path = System.getProperty("HSSF.testdata.path"); | |||
// first check a file with 1900 Date Windowing | |||
String filename = path + "/1900DateWindowing.xls"; | |||
writeCell(filename, 0, (short) 1, date); | |||
assertEquals("Date from file using 1900 Date Windowing", | |||
date.getTime(), | |||
readCell(filename, 0, (short) 1).getTime()); | |||
// now check a file with 1904 Date Windowing | |||
filename = path + "/1904DateWindowing.xls"; | |||
writeCell(filename, 0, (short) 1, date); | |||
assertEquals("Date from file using 1900 Date Windowing", | |||
date.getTime(), | |||
readCell(filename, 0, (short) 1).getTime()); | |||
} | |||
/** | |||
* Sets cell value and writes file. | |||
*/ | |||
private void writeCell(String filename, | |||
int rowIdx, short colIdx, Date date) throws Exception { | |||
FileInputStream stream = new FileInputStream(filename); | |||
POIFSFileSystem fs = new POIFSFileSystem(stream); | |||
HSSFWorkbook workbook = new HSSFWorkbook(fs); | |||
HSSFSheet sheet = workbook.getSheetAt(0); | |||
HSSFRow row = sheet.getRow(rowIdx); | |||
HSSFCell cell = row.getCell(colIdx); | |||
if (cell == null) { | |||
cell = row.createCell(colIdx); | |||
} | |||
cell.setCellValue(date); | |||
// Write the file | |||
stream.close(); | |||
FileOutputStream oStream = new FileOutputStream(filename); | |||
workbook.write(oStream); | |||
oStream.close(); | |||
} | |||
/** | |||
* Reads cell value from file. | |||
*/ | |||
private Date readCell(String filename, | |||
int rowIdx, short colIdx) throws Exception { | |||
FileInputStream stream = new FileInputStream(filename); | |||
POIFSFileSystem fs = new POIFSFileSystem(stream); | |||
HSSFWorkbook workbook = new HSSFWorkbook(fs); | |||
HSSFSheet sheet = workbook.getSheetAt(0); | |||
HSSFRow row = sheet.getRow(rowIdx); | |||
HSSFCell cell = row.getCell(colIdx); | |||
return cell.getDateCellValue(); | |||
} | |||
/** | |||
* Tests that the active cell can be correctly read and set | |||
*/ |
@@ -36,6 +36,8 @@ import org.apache.poi.poifs.filesystem.POIFSFileSystem; | |||
* | |||
* @author Dan Sherman (dsherman at isisph.com) | |||
* @author Hack Kampbjorn (hak at 2mba.dk) | |||
* @author Pavel Krupets (pkrupets at palmtreebusiness dot com) | |||
* @author Alex Jacoby (ajacoby at gmail.com) | |||
* @version %I%, %G% | |||
*/ | |||
@@ -47,7 +49,9 @@ public class TestHSSFDateUtil | |||
public static final int CALENDAR_FEBRUARY = 1; | |||
public static final int CALENDAR_MARCH = 2; | |||
public static final int CALENDAR_APRIL = 3; | |||
public static final int CALENDAR_JULY = 6; | |||
public static final int CALENDAR_OCTOBER = 9; | |||
public TestHSSFDateUtil(String s) | |||
{ | |||
super(s); | |||
@@ -67,10 +71,10 @@ public class TestHSSFDateUtil | |||
GregorianCalendar date = new GregorianCalendar(2002, 0, 1, | |||
hour, 1, 1); | |||
double excelDate = | |||
HSSFDateUtil.getExcelDate(date.getTime()); | |||
HSSFDateUtil.getExcelDate(date.getTime(), false); | |||
assertEquals("Checking hour = " + hour, date.getTime().getTime(), | |||
HSSFDateUtil.getJavaDate(excelDate).getTime()); | |||
HSSFDateUtil.getJavaDate(excelDate, false).getTime()); | |||
} | |||
// check 1900 and 1904 date windowing conversions | |||
@@ -99,7 +103,7 @@ public class TestHSSFDateUtil | |||
public void testExcelConversionOnDSTStart() { | |||
TimeZone cet = TimeZone.getTimeZone("Europe/Copenhagen"); | |||
TimeZone.setDefault(cet); | |||
Calendar cal = new GregorianCalendar(2004, Calendar.MARCH, 28); | |||
Calendar cal = new GregorianCalendar(2004, CALENDAR_MARCH, 28); | |||
for (int hour = 0; hour < 24; hour++) { | |||
// Skip 02:00 CET as that is the Daylight change time | |||
@@ -110,7 +114,7 @@ public class TestHSSFDateUtil | |||
cal.set(Calendar.HOUR_OF_DAY, hour); | |||
Date javaDate = cal.getTime(); | |||
double excelDate = HSSFDateUtil.getExcelDate(javaDate); | |||
double excelDate = HSSFDateUtil.getExcelDate(javaDate, false); | |||
double difference = excelDate - Math.floor(excelDate); | |||
int differenceInHours = (int) (difference * 24 * 60 + 0.5) / 60; | |||
assertEquals("Checking " + hour + " hour on Daylight Saving Time start date", | |||
@@ -118,7 +122,7 @@ public class TestHSSFDateUtil | |||
differenceInHours); | |||
assertEquals("Checking " + hour + " hour on Daylight Saving Time start date", | |||
javaDate.getTime(), | |||
HSSFDateUtil.getJavaDate(excelDate).getTime()); | |||
HSSFDateUtil.getJavaDate(excelDate, false).getTime()); | |||
} | |||
} | |||
@@ -129,8 +133,8 @@ public class TestHSSFDateUtil | |||
public void testJavaConversionOnDSTStart() { | |||
TimeZone cet = TimeZone.getTimeZone("Europe/Copenhagen"); | |||
TimeZone.setDefault(cet); | |||
Calendar cal = new GregorianCalendar(2004, Calendar.MARCH, 28); | |||
double excelDate = HSSFDateUtil.getExcelDate(cal.getTime()); | |||
Calendar cal = new GregorianCalendar(2004, CALENDAR_MARCH, 28); | |||
double excelDate = HSSFDateUtil.getExcelDate(cal.getTime(), false); | |||
double oneHour = 1.0 / 24; | |||
double oneMinute = oneHour / 60; | |||
for (int hour = 0; hour < 24; hour++, excelDate += oneHour) { | |||
@@ -142,10 +146,10 @@ public class TestHSSFDateUtil | |||
} | |||
cal.set(Calendar.HOUR_OF_DAY, hour); | |||
Date javaDate = HSSFDateUtil.getJavaDate(excelDate); | |||
Date javaDate = HSSFDateUtil.getJavaDate(excelDate, false); | |||
assertEquals("Checking " + hour + " hours on Daylight Saving Time start date", | |||
excelDate, | |||
HSSFDateUtil.getExcelDate(javaDate), oneMinute); | |||
HSSFDateUtil.getExcelDate(javaDate, false), oneMinute); | |||
} | |||
} | |||
@@ -156,11 +160,11 @@ public class TestHSSFDateUtil | |||
public void testExcelConversionOnDSTEnd() { | |||
TimeZone cet = TimeZone.getTimeZone("Europe/Copenhagen"); | |||
TimeZone.setDefault(cet); | |||
Calendar cal = new GregorianCalendar(2004, Calendar.OCTOBER, 31); | |||
Calendar cal = new GregorianCalendar(2004, CALENDAR_OCTOBER, 31); | |||
for (int hour = 0; hour < 24; hour++) { | |||
cal.set(Calendar.HOUR_OF_DAY, hour); | |||
Date javaDate = cal.getTime(); | |||
double excelDate = HSSFDateUtil.getExcelDate(javaDate); | |||
double excelDate = HSSFDateUtil.getExcelDate(javaDate, false); | |||
double difference = excelDate - Math.floor(excelDate); | |||
int differenceInHours = (int) (difference * 24 * 60 + 0.5) / 60; | |||
assertEquals("Checking " + hour + " hour on Daylight Saving Time end date", | |||
@@ -168,7 +172,7 @@ public class TestHSSFDateUtil | |||
differenceInHours); | |||
assertEquals("Checking " + hour + " hour on Daylight Saving Time start date", | |||
javaDate.getTime(), | |||
HSSFDateUtil.getJavaDate(excelDate).getTime()); | |||
HSSFDateUtil.getJavaDate(excelDate, false).getTime()); | |||
} | |||
} | |||
@@ -179,16 +183,16 @@ public class TestHSSFDateUtil | |||
public void testJavaConversionOnDSTEnd() { | |||
TimeZone cet = TimeZone.getTimeZone("Europe/Copenhagen"); | |||
TimeZone.setDefault(cet); | |||
Calendar cal = new GregorianCalendar(2004, Calendar.OCTOBER, 31); | |||
double excelDate = HSSFDateUtil.getExcelDate(cal.getTime()); | |||
Calendar cal = new GregorianCalendar(2004, CALENDAR_OCTOBER, 31); | |||
double excelDate = HSSFDateUtil.getExcelDate(cal.getTime(), false); | |||
double oneHour = 1.0 / 24; | |||
double oneMinute = oneHour / 60; | |||
for (int hour = 0; hour < 24; hour++, excelDate += oneHour) { | |||
cal.set(Calendar.HOUR_OF_DAY, hour); | |||
Date javaDate = HSSFDateUtil.getJavaDate(excelDate); | |||
Date javaDate = HSSFDateUtil.getJavaDate(excelDate, false); | |||
assertEquals("Checking " + hour + " hours on Daylight Saving Time start date", | |||
excelDate, | |||
HSSFDateUtil.getExcelDate(javaDate), oneMinute); | |||
HSSFDateUtil.getExcelDate(javaDate, false), oneMinute); | |||
} | |||
} | |||
@@ -315,25 +319,38 @@ public class TestHSSFDateUtil | |||
} | |||
public void testDateBug_2Excel() { | |||
assertEquals(59.0, HSSFDateUtil.getExcelDate(createDate(1900, CALENDAR_FEBRUARY, 28)), 0.00001); | |||
assertEquals(61.0, HSSFDateUtil.getExcelDate(createDate(1900, CALENDAR_MARCH, 1)), 0.00001); | |||
assertEquals(59.0, HSSFDateUtil.getExcelDate(createDate(1900, CALENDAR_FEBRUARY, 28), false), 0.00001); | |||
assertEquals(61.0, HSSFDateUtil.getExcelDate(createDate(1900, CALENDAR_MARCH, 1), false), 0.00001); | |||
assertEquals(37315.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_FEBRUARY, 28)), 0.00001); | |||
assertEquals(37316.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_MARCH, 1)), 0.00001); | |||
assertEquals(37257.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_JANUARY, 1)), 0.00001); | |||
assertEquals(38074.00, HSSFDateUtil.getExcelDate(createDate(2004, CALENDAR_MARCH, 28)), 0.00001); | |||
assertEquals(37315.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_FEBRUARY, 28), false), 0.00001); | |||
assertEquals(37316.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_MARCH, 1), false), 0.00001); | |||
assertEquals(37257.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_JANUARY, 1), false), 0.00001); | |||
assertEquals(38074.00, HSSFDateUtil.getExcelDate(createDate(2004, CALENDAR_MARCH, 28), false), 0.00001); | |||
} | |||
public void testDateBug_2Java() { | |||
assertEquals(createDate(1900, Calendar.FEBRUARY, 28), HSSFDateUtil.getJavaDate(59.0)); | |||
assertEquals(createDate(1900, Calendar.MARCH, 1), HSSFDateUtil.getJavaDate(61.0)); | |||
assertEquals(createDate(1900, CALENDAR_FEBRUARY, 28), HSSFDateUtil.getJavaDate(59.0, false)); | |||
assertEquals(createDate(1900, CALENDAR_MARCH, 1), HSSFDateUtil.getJavaDate(61.0, false)); | |||
assertEquals(createDate(2002, Calendar.FEBRUARY, 28), HSSFDateUtil.getJavaDate(37315.00)); | |||
assertEquals(createDate(2002, Calendar.MARCH, 1), HSSFDateUtil.getJavaDate(37316.00)); | |||
assertEquals(createDate(2002, Calendar.JANUARY, 1), HSSFDateUtil.getJavaDate(37257.00)); | |||
assertEquals(createDate(2004, Calendar.MARCH, 28), HSSFDateUtil.getJavaDate(38074.00)); | |||
assertEquals(createDate(2002, CALENDAR_FEBRUARY, 28), HSSFDateUtil.getJavaDate(37315.00, false)); | |||
assertEquals(createDate(2002, CALENDAR_MARCH, 1), HSSFDateUtil.getJavaDate(37316.00, false)); | |||
assertEquals(createDate(2002, CALENDAR_JANUARY, 1), HSSFDateUtil.getJavaDate(37257.00, false)); | |||
assertEquals(createDate(2004, CALENDAR_MARCH, 28), HSSFDateUtil.getJavaDate(38074.00, false)); | |||
} | |||
public void testDate1904() { | |||
assertEquals(createDate(1904, CALENDAR_JANUARY, 2), HSSFDateUtil.getJavaDate(1.0, true)); | |||
assertEquals(createDate(1904, CALENDAR_JANUARY, 1), HSSFDateUtil.getJavaDate(0.0, true)); | |||
assertEquals(0.0, HSSFDateUtil.getExcelDate(createDate(1904, CALENDAR_JANUARY, 1), true), 0.00001); | |||
assertEquals(1.0, HSSFDateUtil.getExcelDate(createDate(1904, CALENDAR_JANUARY, 2), true), 0.00001); | |||
assertEquals(createDate(1998, CALENDAR_JULY, 5), HSSFDateUtil.getJavaDate(35981, false)); | |||
assertEquals(createDate(1998, CALENDAR_JULY, 5), HSSFDateUtil.getJavaDate(34519, true)); | |||
assertEquals(35981.0, HSSFDateUtil.getExcelDate(createDate(1998, CALENDAR_JULY, 5), false), 0.00001); | |||
assertEquals(34519.0, HSSFDateUtil.getExcelDate(createDate(1998, CALENDAR_JULY, 5), true), 0.00001); | |||
} | |||
private Date createDate(int year, int month, int day) { | |||
Calendar c = new GregorianCalendar(); | |||
c.set(year, month, day, 0, 0, 0); | |||
@@ -341,10 +358,21 @@ public class TestHSSFDateUtil | |||
return c.getTime(); | |||
} | |||
/** | |||
* Check if HSSFDateUtil.getAbsoluteDay works as advertised. | |||
*/ | |||
public void testAbsoluteDay() { | |||
// 1 Jan 1900 is 1 day after 31 Dec 1899 | |||
GregorianCalendar calendar = new GregorianCalendar(1900, 0, 1); | |||
assertEquals("Checking absolute day (1 Jan 1900)", 1, HSSFDateUtil.absoluteDay(calendar, false)); | |||
// 1 Jan 1901 is 366 days after 31 Dec 1899 | |||
calendar = new GregorianCalendar(1901, 0, 1); | |||
assertEquals("Checking absolute day (1 Jan 1901)", 366, HSSFDateUtil.absoluteDay(calendar, false)); | |||
} | |||
public static void main(String [] args) { | |||
System.out | |||
.println("Testing org.apache.poi.hssf.usermodel.TestHSSFDateUtil"); | |||
junit.textui.TestRunner.run(TestHSSFDateUtil.class); | |||
} | |||
} | |||
@@ -63,7 +63,7 @@ public class TestReadWriteChart | |||
//System.out.println("first assertion for date"); | |||
assertEquals(new GregorianCalendar(2000, 0, 1, 10, 51, 2).getTime(), | |||
HSSFDateUtil | |||
.getJavaDate(firstCell.getNumericCellValue())); | |||
.getJavaDate(firstCell.getNumericCellValue(), false)); | |||
HSSFRow row = sheet.createRow(( short ) 15); | |||
HSSFCell cell = row.createCell(( short ) 1); | |||