mirror of https://github.com/apache/poi.git
Fix DAYS360 for US/EU handling
fix forbidden api calls add TimeZone (user) override to DateUtil fix a few left open resources in the junit tests git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1700686 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
82bbbed2b5
commit
2b7c0ef3dd
|
@ -17,7 +17,6 @@
|
||||||
package org.apache.poi.ss.formula.functions;
|
package org.apache.poi.ss.formula.functions;
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.GregorianCalendar;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
@ -28,10 +27,44 @@ import org.apache.poi.ss.formula.eval.ValueEval;
|
||||||
import org.apache.poi.ss.usermodel.DateUtil;
|
import org.apache.poi.ss.usermodel.DateUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the number of days between two dates based on a 360-day year
|
* <p>Calculates the number of days between two dates based on a 360-day year
|
||||||
* (twelve 30-day months), which is used in some accounting calculations. Use
|
* (twelve 30-day months), which is used in some accounting calculations. Use
|
||||||
* this function to help compute payments if your accounting system is based on
|
* this function to help compute payments if your accounting system is based on
|
||||||
* twelve 30-day months.
|
* twelve 30-day months.<p>
|
||||||
|
*
|
||||||
|
* {@code DAYS360(start_date,end_date,[method])}
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>Start_date, end_date (required):<br/>
|
||||||
|
* The two dates between which you want to know the number of days.<br/>
|
||||||
|
* If start_date occurs after end_date, the DAYS360 function returns a negative number.</li>
|
||||||
|
*
|
||||||
|
* <li>Method (optional):<br/>
|
||||||
|
* A logical value that specifies whether to use the U.S. or European method in the calculation</li>
|
||||||
|
*
|
||||||
|
* <li>Method set to false or omitted:<br/>
|
||||||
|
* the DAYS360 function uses the U.S. (NASD) method. If the starting date is the 31st of a month,
|
||||||
|
* it becomes equal to the 30th of the same month. If the ending date is the 31st of a month and
|
||||||
|
* the starting date is earlier than the 30th of a month, the ending date becomes equal to the
|
||||||
|
* 1st of the next month, otherwise the ending date becomes equal to the 30th of the same month.
|
||||||
|
* The month February and leap years are handled in the following way:<br/>
|
||||||
|
* On a non-leap year the function {@code =DAYS360("2/28/93", "3/1/93", FALSE)} returns 1 day
|
||||||
|
* because the DAYS360 function ignores the extra days added to February.<br/>
|
||||||
|
* On a leap year the function {@code =DAYS360("2/29/96","3/1/96", FALSE)} returns 1 day for
|
||||||
|
* the same reason.</li>
|
||||||
|
*
|
||||||
|
* <li>Method Set to true:<br/>
|
||||||
|
* When you set the method parameter to TRUE, the DAYS360 function uses the European method.
|
||||||
|
* Starting dates or ending dates that occur on the 31st of a month become equal to the 30th of
|
||||||
|
* the same month. The month February and leap years are handled in the following way:<br/>
|
||||||
|
* On a non-leap year the function {@code =DAYS360("2/28/93", "3/1/93", TRUE)} returns
|
||||||
|
* 3 days because the DAYS360 function is counting the extra days added to February to give
|
||||||
|
* February 30 days.<br/>
|
||||||
|
* On a leap year the function {@code =DAYS360("2/29/96", "3/1/96", TRUE)} returns
|
||||||
|
* 2 days for the same reason.</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @see <a href="https://support.microsoft.com/en-us/kb/235575">DAYS360 Function Produces Different Values Depending on the Version of Excel</a>
|
||||||
*/
|
*/
|
||||||
public class Days360 extends Var2or3ArgFunction {
|
public class Days360 extends Var2or3ArgFunction {
|
||||||
/**
|
/**
|
||||||
|
@ -68,56 +101,57 @@ public class Days360 extends Var2or3ArgFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double evaluate(double d0, double d1, boolean method) {
|
private static double evaluate(double d0, double d1, boolean method) {
|
||||||
Calendar startingDate = getStartingDate(d0);
|
Calendar realStart = getDate(d0);
|
||||||
Calendar endingDate = getEndingDateAccordingToStartingDate(d1, startingDate);
|
Calendar realEnd = getDate(d1);
|
||||||
long startingDay = startingDate.get(Calendar.MONTH) * 30 + startingDate.get(Calendar.DAY_OF_MONTH);
|
int startingDate[] = getStartingDate(realStart, method);
|
||||||
long endingDay = (endingDate.get(Calendar.YEAR) - startingDate.get(Calendar.YEAR)) * 360
|
int endingDate[] = getEndingDate(realEnd, realStart, method);
|
||||||
+ endingDate.get(Calendar.MONTH) * 30 + endingDate.get(Calendar.DAY_OF_MONTH);
|
|
||||||
return endingDay - startingDay;
|
return
|
||||||
|
(endingDate[0]*360+endingDate[1]*30+endingDate[2])-
|
||||||
|
(startingDate[0]*360+startingDate[1]*30+startingDate[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Calendar getDate(double date) {
|
private static Calendar getDate(double date) {
|
||||||
Calendar processedDate = new GregorianCalendar(DEFAULT_TIMEZONE, Locale.ROOT);
|
Calendar processedDate = Calendar.getInstance(DEFAULT_TIMEZONE, Locale.ROOT);
|
||||||
processedDate.setTime(DateUtil.getJavaDate(date, false));
|
processedDate.setTime(DateUtil.getJavaDate(date, false, DEFAULT_TIMEZONE));
|
||||||
return processedDate;
|
return processedDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Calendar getStartingDate(double date) {
|
private static int[] getStartingDate(Calendar realStart, boolean method) {
|
||||||
Calendar startingDate = getDate(date);
|
Calendar d = realStart;
|
||||||
if (isLastDayOfMonth(startingDate)) {
|
int yyyy = d.get(Calendar.YEAR);
|
||||||
startingDate.set(Calendar.DAY_OF_MONTH, 30);
|
int mm = d.get(Calendar.MONTH);
|
||||||
}
|
int dd = Math.min(30, d.get(Calendar.DAY_OF_MONTH));
|
||||||
return startingDate;
|
|
||||||
|
if (method == false && isLastDayOfMonth(d)) dd = 30;
|
||||||
|
|
||||||
|
return new int[]{yyyy,mm,dd};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Calendar getEndingDateAccordingToStartingDate(double date, Calendar startingDate) {
|
private static int[] getEndingDate(Calendar realEnd, Calendar realStart, boolean method) {
|
||||||
Calendar endingDate = getDate(date);
|
Calendar d = realEnd;
|
||||||
endingDate.setTime(DateUtil.getJavaDate(date, false));
|
int yyyy = d.get(Calendar.YEAR);
|
||||||
if (isLastDayOfMonth(endingDate)) {
|
int mm = d.get(Calendar.MONTH);
|
||||||
if (startingDate.get(Calendar.DATE) < 30) {
|
int dd = Math.min(30, d.get(Calendar.DAY_OF_MONTH));
|
||||||
endingDate = getFirstDayOfNextMonth(endingDate);
|
|
||||||
|
if (method == false && realEnd.get(Calendar.DAY_OF_MONTH) == 31) {
|
||||||
|
if (realStart.get(Calendar.DAY_OF_MONTH) < 30) {
|
||||||
|
d.set(Calendar.DAY_OF_MONTH, 1);
|
||||||
|
d.add(Calendar.MONTH, 1);
|
||||||
|
yyyy = d.get(Calendar.YEAR);
|
||||||
|
mm = d.get(Calendar.MONTH);
|
||||||
|
dd = 1;
|
||||||
|
} else {
|
||||||
|
dd = 30;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return endingDate;
|
|
||||||
|
return new int[]{yyyy,mm,dd};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isLastDayOfMonth(Calendar date) {
|
private static boolean isLastDayOfMonth(Calendar date) {
|
||||||
Calendar clone = (Calendar) date.clone();
|
int dayOfMonth = date.get(Calendar.DAY_OF_MONTH);
|
||||||
clone.add(java.util.Calendar.MONTH, 1);
|
int lastDayOfMonth = date.getActualMaximum(Calendar.DAY_OF_MONTH);
|
||||||
clone.add(java.util.Calendar.DAY_OF_MONTH, -1);
|
return (dayOfMonth == lastDayOfMonth);
|
||||||
int lastDayOfMonth = clone.get(Calendar.DAY_OF_MONTH);
|
|
||||||
return date.get(Calendar.DAY_OF_MONTH) == lastDayOfMonth;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Calendar getFirstDayOfNextMonth(Calendar date) {
|
|
||||||
Calendar newDate = (Calendar) date.clone();
|
|
||||||
if (date.get(Calendar.MONTH) < Calendar.DECEMBER) {
|
|
||||||
newDate.set(Calendar.MONTH, date.get(Calendar.MONTH) + 1);
|
|
||||||
} else {
|
|
||||||
newDate.set(Calendar.MONTH, 1);
|
|
||||||
newDate.set(Calendar.YEAR, date.get(Calendar.YEAR) + 1);
|
|
||||||
}
|
|
||||||
newDate.set(Calendar.DATE, 1);
|
|
||||||
return newDate;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ package org.apache.poi.ss.usermodel;
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@ -79,7 +78,7 @@ public class DateUtil {
|
||||||
* @param use1904windowing Should 1900 or 1904 date windowing be used?
|
* @param use1904windowing Should 1900 or 1904 date windowing be used?
|
||||||
*/
|
*/
|
||||||
public static double getExcelDate(Date date, boolean use1904windowing) {
|
public static double getExcelDate(Date date, boolean use1904windowing) {
|
||||||
Calendar calStart = new GregorianCalendar(TIMEZONE_UTC, Locale.ROOT);
|
Calendar calStart = Calendar.getInstance(getUserTimeZone(), Locale.ROOT);
|
||||||
calStart.setTime(date); // If date includes hours, minutes, and seconds, set them to 0
|
calStart.setTime(date); // If date includes hours, minutes, and seconds, set them to 0
|
||||||
return internalGetExcelDate(calStart, use1904windowing);
|
return internalGetExcelDate(calStart, use1904windowing);
|
||||||
}
|
}
|
||||||
|
@ -315,9 +314,9 @@ public class DateUtil {
|
||||||
int millisecondsInDay = (int)((date - wholeDays) * DAY_MILLISECONDS + 0.5);
|
int millisecondsInDay = (int)((date - wholeDays) * DAY_MILLISECONDS + 0.5);
|
||||||
Calendar calendar;
|
Calendar calendar;
|
||||||
if (timeZone != null) {
|
if (timeZone != null) {
|
||||||
calendar = new GregorianCalendar(timeZone, Locale.ROOT);
|
calendar = Calendar.getInstance(timeZone, Locale.ROOT);
|
||||||
} else {
|
} else {
|
||||||
calendar = new GregorianCalendar(TIMEZONE_UTC, Locale.ROOT); // using default time-zone
|
calendar = Calendar.getInstance(getUserTimeZone(), Locale.ROOT); // using default time-zone
|
||||||
}
|
}
|
||||||
setCalendar(calendar, wholeDays, millisecondsInDay, use1904windowing, roundSeconds);
|
setCalendar(calendar, wholeDays, millisecondsInDay, use1904windowing, roundSeconds);
|
||||||
return calendar;
|
return calendar;
|
||||||
|
@ -335,6 +334,13 @@ public class DateUtil {
|
||||||
private static ThreadLocal<String> lastFormatString = new ThreadLocal<String>();
|
private static ThreadLocal<String> lastFormatString = new ThreadLocal<String>();
|
||||||
private static ThreadLocal<Boolean> lastCachedResult = new ThreadLocal<Boolean>();
|
private static ThreadLocal<Boolean> lastCachedResult = new ThreadLocal<Boolean>();
|
||||||
|
|
||||||
|
private static ThreadLocal<TimeZone> userTimeZone = new ThreadLocal<TimeZone>() {
|
||||||
|
@Override
|
||||||
|
protected TimeZone initialValue() {
|
||||||
|
return TIMEZONE_UTC;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private static boolean isCached(String formatString, int formatIndex) {
|
private static boolean isCached(String formatString, int formatIndex) {
|
||||||
String cachedFormatString = lastFormatString.get();
|
String cachedFormatString = lastFormatString.get();
|
||||||
return cachedFormatString != null && formatIndex == lastFormatIndex.get()
|
return cachedFormatString != null && formatIndex == lastFormatIndex.get()
|
||||||
|
@ -347,6 +353,23 @@ public class DateUtil {
|
||||||
lastCachedResult.set(Boolean.valueOf(cached));
|
lastCachedResult.set(Boolean.valueOf(cached));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* as timezone information is not stored in any format, it can be
|
||||||
|
* set before any date calculations take place
|
||||||
|
*
|
||||||
|
* @param timezone the timezone under which date calculations take place
|
||||||
|
*/
|
||||||
|
public static void setUserTimeZone(TimeZone timezone) {
|
||||||
|
userTimeZone.set(timezone);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the time zone which is used for date calculations
|
||||||
|
*/
|
||||||
|
public static TimeZone getUserTimeZone() {
|
||||||
|
return userTimeZone.get();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a format ID and its format String, will check to see if the
|
* Given a format ID and its format String, will check to see if the
|
||||||
* format represents a date format or not.
|
* format represents a date format or not.
|
||||||
|
@ -661,7 +684,7 @@ public class DateUtil {
|
||||||
int month = parseInt(monthStr, "month", 1, 12);
|
int month = parseInt(monthStr, "month", 1, 12);
|
||||||
int day = parseInt(dayStr, "day", 1, 31);
|
int day = parseInt(dayStr, "day", 1, 31);
|
||||||
|
|
||||||
Calendar cal = new GregorianCalendar(TIMEZONE_UTC, Locale.ROOT);
|
Calendar cal = Calendar.getInstance(getUserTimeZone(), Locale.ROOT);
|
||||||
cal.set(year, month-1, day, 0, 0, 0);
|
cal.set(year, month-1, day, 0, 0, 0);
|
||||||
cal.set(Calendar.MILLISECOND, 0);
|
cal.set(Calendar.MILLISECOND, 0);
|
||||||
return cal.getTime();
|
return cal.getTime();
|
||||||
|
|
|
@ -39,6 +39,7 @@ import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import org.apache.poi.EncryptedDocumentException;
|
import org.apache.poi.EncryptedDocumentException;
|
||||||
import org.apache.poi.hssf.HSSFITestDataProvider;
|
import org.apache.poi.hssf.HSSFITestDataProvider;
|
||||||
|
@ -68,6 +69,7 @@ import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues;
|
||||||
import org.apache.poi.ss.usermodel.Cell;
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
import org.apache.poi.ss.usermodel.CellStyle;
|
import org.apache.poi.ss.usermodel.CellStyle;
|
||||||
import org.apache.poi.ss.usermodel.DataFormatter;
|
import org.apache.poi.ss.usermodel.DataFormatter;
|
||||||
|
import org.apache.poi.ss.usermodel.DateUtil;
|
||||||
import org.apache.poi.ss.usermodel.FormulaEvaluator;
|
import org.apache.poi.ss.usermodel.FormulaEvaluator;
|
||||||
import org.apache.poi.ss.usermodel.Name;
|
import org.apache.poi.ss.usermodel.Name;
|
||||||
import org.apache.poi.ss.usermodel.Row;
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
|
@ -1730,8 +1732,8 @@ public final class TestBugs extends BaseTestBugzillaIssues {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void bug46664() throws Exception {
|
public void bug46664() throws Exception {
|
||||||
HSSFWorkbook wb = new HSSFWorkbook();
|
HSSFWorkbook wb1 = new HSSFWorkbook();
|
||||||
HSSFSheet sheet = wb.createSheet("new_sheet");
|
HSSFSheet sheet = wb1.createSheet("new_sheet");
|
||||||
HSSFRow row = sheet.createRow((short)0);
|
HSSFRow row = sheet.createRow((short)0);
|
||||||
row.createCell(0).setCellValue(new HSSFRichTextString("Column A"));
|
row.createCell(0).setCellValue(new HSSFRichTextString("Column A"));
|
||||||
row.createCell(1).setCellValue(new HSSFRichTextString("Column B"));
|
row.createCell(1).setCellValue(new HSSFRichTextString("Column B"));
|
||||||
|
@ -1741,7 +1743,7 @@ public final class TestBugs extends BaseTestBugzillaIssues {
|
||||||
row.createCell(5).setCellValue(new HSSFRichTextString("Column F"));
|
row.createCell(5).setCellValue(new HSSFRichTextString("Column F"));
|
||||||
|
|
||||||
//set print area from column a to column c (on first row)
|
//set print area from column a to column c (on first row)
|
||||||
wb.setPrintArea(
|
wb1.setPrintArea(
|
||||||
0, //sheet index
|
0, //sheet index
|
||||||
0, //start column
|
0, //start column
|
||||||
2, //end column
|
2, //end column
|
||||||
|
@ -1749,11 +1751,12 @@ public final class TestBugs extends BaseTestBugzillaIssues {
|
||||||
0 //end row
|
0 //end row
|
||||||
);
|
);
|
||||||
|
|
||||||
wb = writeOutAndReadBack(wb);
|
HSSFWorkbook wb2 = writeOutAndReadBack(wb1);
|
||||||
|
wb1.close();
|
||||||
|
|
||||||
// Ensure the tab index
|
// Ensure the tab index
|
||||||
TabIdRecord tr = null;
|
TabIdRecord tr = null;
|
||||||
for(Record r : wb.getWorkbook().getRecords()) {
|
for(Record r : wb2.getWorkbook().getRecords()) {
|
||||||
if(r instanceof TabIdRecord) {
|
if(r instanceof TabIdRecord) {
|
||||||
tr = (TabIdRecord)r;
|
tr = (TabIdRecord)r;
|
||||||
}
|
}
|
||||||
|
@ -1763,20 +1766,21 @@ public final class TestBugs extends BaseTestBugzillaIssues {
|
||||||
assertEquals(0, tr._tabids[0]);
|
assertEquals(0, tr._tabids[0]);
|
||||||
|
|
||||||
// Ensure the print setup
|
// Ensure the print setup
|
||||||
assertEquals("new_sheet!$A$1:$C$1", wb.getPrintArea(0));
|
assertEquals("new_sheet!$A$1:$C$1", wb2.getPrintArea(0));
|
||||||
assertEquals("new_sheet!$A$1:$C$1", wb.getName("Print_Area").getRefersToFormula());
|
assertEquals("new_sheet!$A$1:$C$1", wb2.getName("Print_Area").getRefersToFormula());
|
||||||
|
|
||||||
// Needs reference not value
|
// Needs reference not value
|
||||||
NameRecord nr = wb.getWorkbook().getNameRecord(
|
NameRecord nr = wb2.getWorkbook().getNameRecord(
|
||||||
wb.getNameIndex("Print_Area")
|
wb2.getNameIndex("Print_Area")
|
||||||
);
|
);
|
||||||
assertEquals("Print_Area", nr.getNameText());
|
assertEquals("Print_Area", nr.getNameText());
|
||||||
assertEquals(1, nr.getNameDefinition().length);
|
assertEquals(1, nr.getNameDefinition().length);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"new_sheet!$A$1:$C$1",
|
"new_sheet!$A$1:$C$1",
|
||||||
((Area3DPtg)nr.getNameDefinition()[0]).toFormulaString(HSSFEvaluationWorkbook.create(wb))
|
((Area3DPtg)nr.getNameDefinition()[0]).toFormulaString(HSSFEvaluationWorkbook.create(wb2))
|
||||||
);
|
);
|
||||||
assertEquals('R', nr.getNameDefinition()[0].getRVAType());
|
assertEquals('R', nr.getNameDefinition()[0].getRVAType());
|
||||||
|
wb2.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1932,14 +1936,14 @@ public final class TestBugs extends BaseTestBugzillaIssues {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void bug49689() throws Exception {
|
public void bug49689() throws Exception {
|
||||||
HSSFWorkbook wb = new HSSFWorkbook();
|
HSSFWorkbook wb1 = new HSSFWorkbook();
|
||||||
HSSFSheet s = wb.createSheet("Test");
|
HSSFSheet s = wb1.createSheet("Test");
|
||||||
HSSFRow r = s.createRow(0);
|
HSSFRow r = s.createRow(0);
|
||||||
HSSFCell c = r.createCell(0);
|
HSSFCell c = r.createCell(0);
|
||||||
|
|
||||||
HSSFCellStyle cs1 = wb.createCellStyle();
|
HSSFCellStyle cs1 = wb1.createCellStyle();
|
||||||
HSSFCellStyle cs2 = wb.createCellStyle();
|
HSSFCellStyle cs2 = wb1.createCellStyle();
|
||||||
HSSFCellStyle cs3 = wb.createCellStyle();
|
HSSFCellStyle cs3 = wb1.createCellStyle();
|
||||||
|
|
||||||
assertEquals(21, cs1.getIndex());
|
assertEquals(21, cs1.getIndex());
|
||||||
cs1.setUserStyleName("Testing");
|
cs1.setUserStyleName("Testing");
|
||||||
|
@ -1954,12 +1958,14 @@ public final class TestBugs extends BaseTestBugzillaIssues {
|
||||||
c.setCellStyle(cs1);
|
c.setCellStyle(cs1);
|
||||||
|
|
||||||
// Write out and read back
|
// Write out and read back
|
||||||
wb = writeOutAndReadBack(wb);
|
HSSFWorkbook wb2 = writeOutAndReadBack(wb1);
|
||||||
|
|
||||||
// Re-check
|
// Re-check
|
||||||
assertEquals("Testing", wb.getCellStyleAt((short)21).getUserStyleName());
|
assertEquals("Testing", wb2.getCellStyleAt((short)21).getUserStyleName());
|
||||||
assertEquals("Testing 2", wb.getCellStyleAt((short)22).getUserStyleName());
|
assertEquals("Testing 2", wb2.getCellStyleAt((short)22).getUserStyleName());
|
||||||
assertEquals("Testing 3", wb.getCellStyleAt((short)23).getUserStyleName());
|
assertEquals("Testing 3", wb2.getCellStyleAt((short)23).getUserStyleName());
|
||||||
|
|
||||||
|
wb2.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -2187,6 +2193,10 @@ public final class TestBugs extends BaseTestBugzillaIssues {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void bug48968() throws Exception {
|
public void bug48968() throws Exception {
|
||||||
|
TimeZone tz = DateUtil.getUserTimeZone();
|
||||||
|
try {
|
||||||
|
DateUtil.setUserTimeZone(TimeZone.getTimeZone("CET"));
|
||||||
|
|
||||||
HSSFWorkbook wb = openSample("48968.xls");
|
HSSFWorkbook wb = openSample("48968.xls");
|
||||||
assertEquals(1, wb.getNumberOfSheets());
|
assertEquals(1, wb.getNumberOfSheets());
|
||||||
|
|
||||||
|
@ -2231,7 +2241,11 @@ public final class TestBugs extends BaseTestBugzillaIssues {
|
||||||
assertEquals(39.0+14.0+1, s.getRow(6).getCell(0).getNumericCellValue(), 0);
|
assertEquals(39.0+14.0+1, s.getRow(6).getCell(0).getNumericCellValue(), 0);
|
||||||
assertEquals("SECOND(A1)", s.getRow(7).getCell(0).getCellFormula());
|
assertEquals("SECOND(A1)", s.getRow(7).getCell(0).getCellFormula());
|
||||||
assertEquals(54.0+24.0-60, s.getRow(7).getCell(0).getNumericCellValue(), 0);
|
assertEquals(54.0+24.0-60, s.getRow(7).getCell(0).getNumericCellValue(), 0);
|
||||||
|
} finally {
|
||||||
|
DateUtil.setUserTimeZone(tz);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mixture of Ascii and Unicode strings in a
|
* Mixture of Ascii and Unicode strings in a
|
||||||
|
@ -2418,23 +2432,25 @@ public final class TestBugs extends BaseTestBugzillaIssues {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void bug53432() throws IOException{
|
public void bug53432() throws IOException{
|
||||||
Workbook wb = new HSSFWorkbook(); //or new HSSFWorkbook();
|
Workbook wb1 = new HSSFWorkbook(); //or new HSSFWorkbook();
|
||||||
wb.addPicture(new byte[]{123,22}, Workbook.PICTURE_TYPE_JPEG);
|
wb1.addPicture(new byte[]{123,22}, Workbook.PICTURE_TYPE_JPEG);
|
||||||
assertEquals(wb.getAllPictures().size(), 1);
|
assertEquals(wb1.getAllPictures().size(), 1);
|
||||||
wb.close();
|
wb1.close();
|
||||||
|
|
||||||
wb.close();
|
wb1.close();
|
||||||
wb = new HSSFWorkbook();
|
wb1 = new HSSFWorkbook();
|
||||||
|
|
||||||
wb = writeOutAndReadBack((HSSFWorkbook) wb);
|
Workbook wb2 = writeOutAndReadBack((HSSFWorkbook) wb1);
|
||||||
assertEquals(wb.getAllPictures().size(), 0);
|
wb1.close();
|
||||||
wb.addPicture(new byte[]{123,22}, Workbook.PICTURE_TYPE_JPEG);
|
assertEquals(wb2.getAllPictures().size(), 0);
|
||||||
assertEquals(wb.getAllPictures().size(), 1);
|
wb2.addPicture(new byte[]{123,22}, Workbook.PICTURE_TYPE_JPEG);
|
||||||
|
assertEquals(wb2.getAllPictures().size(), 1);
|
||||||
|
|
||||||
wb = writeOutAndReadBack((HSSFWorkbook) wb);
|
Workbook wb3 = writeOutAndReadBack((HSSFWorkbook) wb2);
|
||||||
assertEquals(wb.getAllPictures().size(), 1);
|
wb2.close();
|
||||||
|
assertEquals(wb3.getAllPictures().size(), 1);
|
||||||
|
|
||||||
wb.close();
|
wb3.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -2539,30 +2555,34 @@ public final class TestBugs extends BaseTestBugzillaIssues {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void bug56325() throws IOException {
|
public void bug56325() throws IOException {
|
||||||
HSSFWorkbook wb;
|
HSSFWorkbook wb1;
|
||||||
|
|
||||||
File file = HSSFTestDataSamples.getSampleFile("56325.xls");
|
File file = HSSFTestDataSamples.getSampleFile("56325.xls");
|
||||||
InputStream stream = new FileInputStream(file);
|
InputStream stream = new FileInputStream(file);
|
||||||
try {
|
try {
|
||||||
POIFSFileSystem fs = new POIFSFileSystem(stream);
|
POIFSFileSystem fs = new POIFSFileSystem(stream);
|
||||||
wb = new HSSFWorkbook(fs);
|
wb1 = new HSSFWorkbook(fs);
|
||||||
} finally {
|
} finally {
|
||||||
stream.close();
|
stream.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(3, wb.getNumberOfSheets());
|
assertEquals(3, wb1.getNumberOfSheets());
|
||||||
wb.removeSheetAt(0);
|
wb1.removeSheetAt(0);
|
||||||
assertEquals(2, wb.getNumberOfSheets());
|
assertEquals(2, wb1.getNumberOfSheets());
|
||||||
|
|
||||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1);
|
||||||
assertEquals(2, wb.getNumberOfSheets());
|
wb1.close();
|
||||||
wb.removeSheetAt(0);
|
assertEquals(2, wb2.getNumberOfSheets());
|
||||||
assertEquals(1, wb.getNumberOfSheets());
|
wb2.removeSheetAt(0);
|
||||||
wb.removeSheetAt(0);
|
assertEquals(1, wb2.getNumberOfSheets());
|
||||||
assertEquals(0, wb.getNumberOfSheets());
|
wb2.removeSheetAt(0);
|
||||||
|
assertEquals(0, wb2.getNumberOfSheets());
|
||||||
|
|
||||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
HSSFWorkbook wb3 = HSSFTestDataSamples.writeOutAndReadBack(wb2);
|
||||||
assertEquals(0, wb.getNumberOfSheets());
|
wb2.close();
|
||||||
|
|
||||||
|
assertEquals(0, wb3.getNumberOfSheets());
|
||||||
|
wb3.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -18,10 +18,11 @@
|
||||||
package org.apache.poi.hssf.usermodel;
|
package org.apache.poi.hssf.usermodel;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.Locale;
|
||||||
import junit.framework.AssertionFailedError;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import org.apache.poi.hssf.HSSFITestDataProvider;
|
import org.apache.poi.hssf.HSSFITestDataProvider;
|
||||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||||
|
@ -38,6 +39,8 @@ import org.apache.poi.ss.usermodel.Row;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
|
||||||
|
import junit.framework.AssertionFailedError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests various functionality having to do with {@link HSSFCell}. For instance support for
|
* Tests various functionality having to do with {@link HSSFCell}. For instance support for
|
||||||
* particular datatypes, etc.
|
* particular datatypes, etc.
|
||||||
|
@ -57,7 +60,9 @@ public final class TestHSSFCell extends BaseTestCell {
|
||||||
* but there's a separate unit test for that.
|
* but there's a separate unit test for that.
|
||||||
*/
|
*/
|
||||||
public void testDateWindowingRead() {
|
public void testDateWindowingRead() {
|
||||||
GregorianCalendar cal = new GregorianCalendar(2000,0,1); // Jan. 1, 2000
|
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ROOT);
|
||||||
|
cal.set(2000, 0, 1, 0, 0, 0); // Jan. 1, 2000
|
||||||
|
cal.clear(Calendar.MILLISECOND);
|
||||||
Date date = cal.getTime();
|
Date date = cal.getTime();
|
||||||
|
|
||||||
// first check a file with 1900 Date Windowing
|
// first check a file with 1900 Date Windowing
|
||||||
|
|
|
@ -17,30 +17,26 @@
|
||||||
|
|
||||||
package org.apache.poi.ss.formula.eval;
|
package org.apache.poi.ss.formula.eval;
|
||||||
|
|
||||||
import junit.framework.Test;
|
import org.junit.runner.RunWith;
|
||||||
import junit.framework.TestSuite;
|
import org.junit.runners.Suite;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collects all tests the package <tt>org.apache.poi.hssf.record.formula.eval</tt>.
|
* Collects all tests the package <tt>org.apache.poi.hssf.record.formula.eval</tt>.
|
||||||
*
|
|
||||||
* @author Josh Micich
|
|
||||||
*/
|
*/
|
||||||
|
@RunWith(Suite.class)
|
||||||
|
@Suite.SuiteClasses({
|
||||||
|
TestAreaEval.class,
|
||||||
|
TestHSSFCircularReferences.class,
|
||||||
|
TestDivideEval.class,
|
||||||
|
TestEqualEval.class,
|
||||||
|
TestExternalFunction.class,
|
||||||
|
TestFormulaBugs.class,
|
||||||
|
TestFormulasFromSpreadsheet.class,
|
||||||
|
TestMinusZeroResult.class,
|
||||||
|
TestMissingArgEval.class,
|
||||||
|
TestPercentEval.class,
|
||||||
|
TestRangeEval.class,
|
||||||
|
TestUnaryPlusEval.class,
|
||||||
|
})
|
||||||
public class AllFormulaEvalTests {
|
public class AllFormulaEvalTests {
|
||||||
|
|
||||||
public static Test suite() {
|
|
||||||
TestSuite result = new TestSuite(AllFormulaEvalTests.class.getName());
|
|
||||||
result.addTestSuite(TestAreaEval.class);
|
|
||||||
result.addTestSuite(TestHSSFCircularReferences.class);
|
|
||||||
result.addTestSuite(TestDivideEval.class);
|
|
||||||
result.addTestSuite(TestEqualEval.class);
|
|
||||||
result.addTestSuite(TestExternalFunction.class);
|
|
||||||
result.addTestSuite(TestFormulaBugs.class);
|
|
||||||
result.addTestSuite(TestFormulasFromSpreadsheet.class);
|
|
||||||
result.addTestSuite(TestMinusZeroResult.class);
|
|
||||||
result.addTestSuite(TestMissingArgEval.class);
|
|
||||||
result.addTestSuite(TestPercentEval.class);
|
|
||||||
result.addTestSuite(TestRangeEval.class);
|
|
||||||
result.addTestSuite(TestUnaryPlusEval.class);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,24 +17,30 @@
|
||||||
|
|
||||||
package org.apache.poi.ss.formula.eval;
|
package org.apache.poi.ss.formula.eval;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
|
||||||
import junit.framework.AssertionFailedError;
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||||
import org.apache.poi.ss.formula.functions.TestMathX;
|
|
||||||
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
|
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
|
import org.apache.poi.ss.formula.functions.TestMathX;
|
||||||
import org.apache.poi.ss.usermodel.Cell;
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
import org.apache.poi.ss.usermodel.CellValue;
|
import org.apache.poi.ss.usermodel.CellValue;
|
||||||
import org.apache.poi.ss.usermodel.Row;
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.poi.util.POILogFactory;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.poi.util.POILogger;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import junit.framework.AssertionFailedError;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests formulas and operators as loaded from a test data spreadsheet.<p/>
|
* Tests formulas and operators as loaded from a test data spreadsheet.<p/>
|
||||||
|
@ -46,7 +52,7 @@ import org.apache.poi.util.POILogger;
|
||||||
*
|
*
|
||||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||||
*/
|
*/
|
||||||
public final class TestFormulasFromSpreadsheet extends TestCase {
|
public final class TestFormulasFromSpreadsheet {
|
||||||
private static final POILogger logger = POILogFactory.getLogger(TestFormulasFromSpreadsheet.class);
|
private static final POILogger logger = POILogFactory.getLogger(TestFormulasFromSpreadsheet.class);
|
||||||
|
|
||||||
private static final class Result {
|
private static final class Result {
|
||||||
|
@ -111,12 +117,8 @@ public final class TestFormulasFromSpreadsheet extends TestCase {
|
||||||
|
|
||||||
|
|
||||||
private static void confirmExpectedResult(String msg, Cell expected, CellValue actual) {
|
private static void confirmExpectedResult(String msg, Cell expected, CellValue actual) {
|
||||||
if (expected == null) {
|
assertNotNull(msg + " - Bad setup data expected value is null", expected);
|
||||||
throw new AssertionFailedError(msg + " - Bad setup data expected value is null");
|
assertNotNull(msg + " - actual value was null", actual);
|
||||||
}
|
|
||||||
if(actual == null) {
|
|
||||||
throw new AssertionFailedError(msg + " - actual value was null");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (expected.getCellType()) {
|
switch (expected.getCellType()) {
|
||||||
case Cell.CELL_TYPE_BLANK:
|
case Cell.CELL_TYPE_BLANK:
|
||||||
|
@ -131,7 +133,7 @@ public final class TestFormulasFromSpreadsheet extends TestCase {
|
||||||
assertEquals(msg, ErrorEval.getText(expected.getErrorCellValue()), ErrorEval.getText(actual.getErrorValue()));
|
assertEquals(msg, ErrorEval.getText(expected.getErrorCellValue()), ErrorEval.getText(actual.getErrorValue()));
|
||||||
break;
|
break;
|
||||||
case Cell.CELL_TYPE_FORMULA: // will never be used, since we will call method after formula evaluation
|
case Cell.CELL_TYPE_FORMULA: // will never be used, since we will call method after formula evaluation
|
||||||
throw new AssertionFailedError("Cannot expect formula as result of formula evaluation: " + msg);
|
fail("Cannot expect formula as result of formula evaluation: " + msg);
|
||||||
case Cell.CELL_TYPE_NUMERIC:
|
case Cell.CELL_TYPE_NUMERIC:
|
||||||
assertEquals(msg, Cell.CELL_TYPE_NUMERIC, actual.getCellType());
|
assertEquals(msg, Cell.CELL_TYPE_NUMERIC, actual.getCellType());
|
||||||
TestMathX.assertEquals(msg, expected.getNumericCellValue(), actual.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR);
|
TestMathX.assertEquals(msg, expected.getNumericCellValue(), actual.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR);
|
||||||
|
@ -143,7 +145,7 @@ public final class TestFormulasFromSpreadsheet extends TestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
protected void setUp() {
|
protected void setUp() {
|
||||||
if (workbook == null) {
|
if (workbook == null) {
|
||||||
workbook = HSSFTestDataSamples.openSampleWorkbook(SS.FILENAME);
|
workbook = HSSFTestDataSamples.openSampleWorkbook(SS.FILENAME);
|
||||||
|
@ -155,6 +157,7 @@ public final class TestFormulasFromSpreadsheet extends TestCase {
|
||||||
_evaluationSuccessCount = 0;
|
_evaluationSuccessCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testFunctionsFromTestSpreadsheet() {
|
public void testFunctionsFromTestSpreadsheet() {
|
||||||
|
|
||||||
processFunctionGroup(SS.START_OPERATORS_ROW_INDEX, null);
|
processFunctionGroup(SS.START_OPERATORS_ROW_INDEX, null);
|
||||||
|
@ -167,11 +170,9 @@ public final class TestFormulasFromSpreadsheet extends TestCase {
|
||||||
String successMsg = "There were "
|
String successMsg = "There were "
|
||||||
+ _evaluationSuccessCount + " successful evaluation(s) and "
|
+ _evaluationSuccessCount + " successful evaluation(s) and "
|
||||||
+ _functionSuccessCount + " function(s) without error";
|
+ _functionSuccessCount + " function(s) without error";
|
||||||
if(_functionFailureCount > 0) {
|
|
||||||
String msg = _functionFailureCount + " function(s) failed in "
|
String msg = _functionFailureCount + " function(s) failed in "
|
||||||
+ _evaluationFailureCount + " evaluation(s). " + successMsg;
|
+ _evaluationFailureCount + " evaluation(s). " + successMsg;
|
||||||
throw new AssertionFailedError(msg);
|
assertEquals(msg, _functionFailureCount, 0);
|
||||||
}
|
|
||||||
logger.log(POILogger.INFO, getClass().getName() + ": " + successMsg);
|
logger.log(POILogger.INFO, getClass().getName() + ": " + successMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,11 +189,9 @@ public final class TestFormulasFromSpreadsheet extends TestCase {
|
||||||
while (true) {
|
while (true) {
|
||||||
Row r = sheet.getRow(rowIndex);
|
Row r = sheet.getRow(rowIndex);
|
||||||
String targetFunctionName = getTargetFunctionName(r);
|
String targetFunctionName = getTargetFunctionName(r);
|
||||||
if(targetFunctionName == null) {
|
assertNotNull("Test spreadsheet cell empty on row ("
|
||||||
throw new AssertionFailedError("Test spreadsheet cell empty on row ("
|
|
||||||
+ (rowIndex+1) + "). Expected function name or '"
|
+ (rowIndex+1) + "). Expected function name or '"
|
||||||
+ SS.FUNCTION_NAMES_END_SENTINEL + "'");
|
+ SS.FUNCTION_NAMES_END_SENTINEL + "'", targetFunctionName);
|
||||||
}
|
|
||||||
if(targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) {
|
if(targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) {
|
||||||
// found end of functions list
|
// found end of functions list
|
||||||
break;
|
break;
|
||||||
|
@ -201,11 +200,9 @@ public final class TestFormulasFromSpreadsheet extends TestCase {
|
||||||
|
|
||||||
// expected results are on the row below
|
// expected results are on the row below
|
||||||
Row expectedValuesRow = sheet.getRow(rowIndex + 1);
|
Row expectedValuesRow = sheet.getRow(rowIndex + 1);
|
||||||
if(expectedValuesRow == null) {
|
|
||||||
int missingRowNum = rowIndex + 2; //+1 for 1-based, +1 for next row
|
int missingRowNum = rowIndex + 2; //+1 for 1-based, +1 for next row
|
||||||
throw new AssertionFailedError("Missing expected values row for function '"
|
assertNotNull("Missing expected values row for function '"
|
||||||
+ targetFunctionName + " (row " + missingRowNum + ")");
|
+ targetFunctionName + " (row " + missingRowNum + ")", expectedValuesRow);
|
||||||
}
|
|
||||||
switch(processFunctionRow(evaluator, targetFunctionName, r, expectedValuesRow)) {
|
switch(processFunctionRow(evaluator, targetFunctionName, r, expectedValuesRow)) {
|
||||||
case Result.ALL_EVALUATIONS_SUCCEEDED: _functionSuccessCount++; break;
|
case Result.ALL_EVALUATIONS_SUCCEEDED: _functionSuccessCount++; break;
|
||||||
case Result.SOME_EVALUATIONS_FAILED: _functionFailureCount++; break;
|
case Result.SOME_EVALUATIONS_FAILED: _functionFailureCount++; break;
|
||||||
|
|
|
@ -17,51 +17,47 @@
|
||||||
|
|
||||||
package org.apache.poi.ss.formula.functions;
|
package org.apache.poi.ss.formula.functions;
|
||||||
|
|
||||||
import junit.framework.Test;
|
import org.junit.runner.RunWith;
|
||||||
import junit.framework.TestSuite;
|
import org.junit.runners.Suite;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Direct tests for all implementors of <code>Function</code>.
|
* Direct tests for all implementors of <code>Function</code>.
|
||||||
*
|
|
||||||
* @author Josh Micich
|
|
||||||
*/
|
*/
|
||||||
public final class AllIndividualFunctionEvaluationTests {
|
@RunWith(Suite.class)
|
||||||
|
@Suite.SuiteClasses({
|
||||||
public static Test suite() {
|
TestAverage.class,
|
||||||
TestSuite result = new TestSuite(AllIndividualFunctionEvaluationTests.class.getName());
|
TestCountFuncs.class,
|
||||||
result.addTestSuite(TestAverage.class);
|
TestDate.class,
|
||||||
result.addTestSuite(TestCountFuncs.class);
|
TestDays360.class,
|
||||||
result.addTestSuite(TestDate.class);
|
TestFinanceLib.class,
|
||||||
result.addTestSuite(TestDays360.class);
|
TestFind.class,
|
||||||
result.addTestSuite(TestFinanceLib.class);
|
TestIndex.class,
|
||||||
result.addTestSuite(TestFind.class);
|
TestIndexFunctionFromSpreadsheet.class,
|
||||||
result.addTestSuite(TestIndex.class);
|
TestIndirect.class,
|
||||||
result.addTestSuite(TestIndexFunctionFromSpreadsheet.class);
|
TestIsBlank.class,
|
||||||
result.addTestSuite(TestIndirect.class);
|
TestLen.class,
|
||||||
result.addTestSuite(TestIsBlank.class);
|
TestLookupFunctionsFromSpreadsheet.class,
|
||||||
result.addTestSuite(TestLen.class);
|
TestMatch.class,
|
||||||
result.addTestSuite(TestLookupFunctionsFromSpreadsheet.class);
|
TestMathX.class,
|
||||||
result.addTestSuite(TestMatch.class);
|
TestMid.class,
|
||||||
result.addTestSuite(TestMathX.class);
|
TestNper.class,
|
||||||
result.addTestSuite(TestMid.class);
|
TestOffset.class,
|
||||||
result.addTestSuite(TestNper.class);
|
TestPmt.class,
|
||||||
result.addTestSuite(TestOffset.class);
|
TestRoundFuncs.class,
|
||||||
result.addTestSuite(TestPmt.class);
|
TestRowCol.class,
|
||||||
result.addTestSuite(TestRoundFuncs.class);
|
TestStatsLib.class,
|
||||||
result.addTestSuite(TestRowCol.class);
|
TestSubtotal.class,
|
||||||
result.addTestSuite(TestStatsLib.class);
|
TestSumif.class,
|
||||||
result.addTestSuite(TestSubtotal.class);
|
TestSumproduct.class,
|
||||||
result.addTestSuite(TestSumif.class);
|
TestText.class,
|
||||||
result.addTestSuite(TestSumproduct.class);
|
TestTFunc.class,
|
||||||
result.addTestSuite(TestText.class);
|
TestTime.class,
|
||||||
result.addTestSuite(TestTFunc.class);
|
TestTrim.class,
|
||||||
result.addTestSuite(TestTime.class);
|
TestTrunc.class,
|
||||||
result.addTestSuite(TestTrim.class);
|
TestValue.class,
|
||||||
result.addTestSuite(TestTrunc.class);
|
TestXYNumericFunction.class,
|
||||||
result.addTestSuite(TestValue.class);
|
TestAddress.class,
|
||||||
result.addTestSuite(TestXYNumericFunction.class);
|
TestClean.class
|
||||||
result.addTestSuite(TestAddress.class);
|
})
|
||||||
result.addTestSuite(TestClean.class);
|
public class AllIndividualFunctionEvaluationTests {
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,52 +17,38 @@
|
||||||
|
|
||||||
package org.apache.poi.ss.formula.functions;
|
package org.apache.poi.ss.formula.functions;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import junit.framework.AssertionFailedError;
|
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import org.apache.poi.ss.formula.eval.BoolEval;
|
import org.apache.poi.ss.formula.eval.BoolEval;
|
||||||
import org.apache.poi.ss.formula.eval.NumberEval;
|
import org.apache.poi.ss.formula.eval.NumberEval;
|
||||||
import org.apache.poi.ss.formula.eval.ValueEval;
|
import org.apache.poi.ss.formula.eval.ValueEval;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
public final class TestDays360 {
|
||||||
* @author Josh Micich
|
|
||||||
*/
|
|
||||||
public final class TestDays360 extends TestCase {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param month 1-based
|
* @param month 1-based
|
||||||
*/
|
*/
|
||||||
private static Date makeDate(int year, int month, int day) {
|
private static Date makeDate(int year, int month, int day) {
|
||||||
|
Calendar cal = Calendar.getInstance(Locale.ROOT);
|
||||||
Calendar cal = new GregorianCalendar(year, month-1, day, 0, 0, 0);
|
cal.set(year, month-1, day, 0, 0, 0);
|
||||||
cal.set(Calendar.MILLISECOND, 0);
|
cal.set(Calendar.MILLISECOND, 0);
|
||||||
return cal.getTime();
|
return cal.getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Date decrementDay(Date d) {
|
private static Date decrementDay(Date d) {
|
||||||
Calendar c = new GregorianCalendar(Locale.ROOT);
|
Calendar c = (Calendar)d.clone();
|
||||||
c.setTimeInMillis(d.getTime());
|
|
||||||
c.add(Calendar.DAY_OF_MONTH, -1);
|
c.add(Calendar.DAY_OF_MONTH, -1);
|
||||||
return c.getTime();
|
return c.getTime();
|
||||||
}
|
}
|
||||||
private static String fmt(Date d) {
|
|
||||||
Calendar c = new GregorianCalendar(Locale.ROOT);
|
|
||||||
c.setTimeInMillis(d.getTime());
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append(c.get(Calendar.YEAR));
|
|
||||||
sb.append("/");
|
|
||||||
sb.append(c.get(Calendar.MONTH)+1);
|
|
||||||
sb.append("/");
|
|
||||||
sb.append(c.get(Calendar.DAY_OF_MONTH));
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testBasic() {
|
public void testBasic() {
|
||||||
confirm(120, 2009, 1, 15, 2009, 5, 15);
|
confirm(120, 2009, 1, 15, 2009, 5, 15);
|
||||||
confirm(158, 2009, 1, 26, 2009, 7, 4);
|
confirm(158, 2009, 1, 26, 2009, 7, 4);
|
||||||
|
@ -74,37 +60,47 @@ public final class TestDays360 extends TestCase {
|
||||||
// longer time spans
|
// longer time spans
|
||||||
confirm(562, 2008, 8, 11, 2010, 3, 3);
|
confirm(562, 2008, 8, 11, 2010, 3, 3);
|
||||||
confirm(916, 2007, 2, 23, 2009, 9, 9);
|
confirm(916, 2007, 2, 23, 2009, 9, 9);
|
||||||
|
|
||||||
|
// other tests
|
||||||
|
confirm(1, makeDate(1993, 2, 28), makeDate(1993, 3, 1), false);
|
||||||
|
confirm(1, makeDate(1996, 2, 29), makeDate(1996, 3, 1), false);
|
||||||
|
confirm(-2, makeDate(1993, 2, 28), makeDate(1993, 2, 28), false);
|
||||||
|
confirm(3, makeDate(1993, 2, 28), makeDate(1993, 3, 1), true);
|
||||||
|
confirm(2, makeDate(1996, 2, 29), makeDate(1996, 3, 1), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void confirm(int expResult, int y1, int m1, int d1, int y2, int m2, int d2) {
|
private static void confirm(int expResult, int y1, int m1, int d1, int y2, int m2, int d2) {
|
||||||
confirm(expResult, makeDate(y1, m1, d1), makeDate(y2, m2, d2), false);
|
confirm(expResult, makeDate(y1, m1, d1), makeDate(y2, m2, d2), false);
|
||||||
confirm(-expResult, makeDate(y2, m2, d2), makeDate(y1, m1, d1), false);
|
confirm(-expResult, makeDate(y2, m2, d2), makeDate(y1, m1, d1), false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The <tt>method</tt> parameter only makes a difference when the second parameter
|
* The <tt>method</tt> parameter only makes a difference when the second parameter
|
||||||
* is the last day of the month that does <em>not</em> have 30 days.
|
* is the last day of the month that does <em>not</em> have 30 days.
|
||||||
*/
|
*/
|
||||||
public void DISABLED_testMonthBoundaries() {
|
@Test
|
||||||
|
public void testMonthBoundaries() {
|
||||||
// jan
|
// jan
|
||||||
confirmMonthBoundary(false, 1, 0, 0, 2, 3, 4);
|
confirmMonthBoundary(false, 2001, 1, 0, 0, 2, 3, 4);
|
||||||
confirmMonthBoundary(true, 1, 0, 0, 1, 3, 4);
|
confirmMonthBoundary(true, 2001, 1, 0, 0, 1, 2, 3);
|
||||||
// feb
|
// feb
|
||||||
confirmMonthBoundary(false, 2,-2, 1, 2, 3, 4);
|
confirmMonthBoundary(false, 2001, 2,-2, 1, 2, 3, 4);
|
||||||
confirmMonthBoundary(true, 2, 0, 1, 2, 3, 4);
|
confirmMonthBoundary(true, 2001, 2, 0, 1, 2, 3, 4);
|
||||||
// mar
|
// mar
|
||||||
confirmMonthBoundary(false, 3, 0, 0, 2, 3, 4);
|
confirmMonthBoundary(false, 2001, 3, 0, 0, 2, 3, 4);
|
||||||
confirmMonthBoundary(true, 3, 0, 0, 1, 3, 4);
|
confirmMonthBoundary(true, 2001, 3, 0, 0, 1, 2, 3);
|
||||||
// apr
|
// apr
|
||||||
confirmMonthBoundary(false, 4, 0, 1, 2, 3, 4);
|
confirmMonthBoundary(false, 2001, 4, 0, 1, 2, 3, 4);
|
||||||
confirmMonthBoundary(true, 4, 0, 1, 2, 3, 4);
|
confirmMonthBoundary(true, 2001, 4, 0, 1, 2, 3, 4);
|
||||||
// may
|
// may
|
||||||
confirmMonthBoundary(false, 5, 0, 0, 2, 3, 4);
|
confirmMonthBoundary(false, 2001, 5, 0, 0, 2, 3, 4);
|
||||||
confirmMonthBoundary(true, 5, 0, 0, 1, 3, 4);
|
confirmMonthBoundary(true, 2001, 5, 0, 0, 1, 2, 3);
|
||||||
// jun
|
// jun
|
||||||
confirmMonthBoundary(false, 6, 0, 1, 2, 3, 4);
|
confirmMonthBoundary(false, 2001, 6, 0, 1, 2, 3, 4);
|
||||||
confirmMonthBoundary(true, 6, 0, 1, 2, 3, 4);
|
confirmMonthBoundary(true, 2001, 6, 0, 1, 2, 3, 4);
|
||||||
// etc...
|
// leap year
|
||||||
|
confirmMonthBoundary(false, 2012, 2, -1, 1, 2, 3, 4);
|
||||||
|
confirmMonthBoundary(true, 2012, 2, 0, 1, 2, 3, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,13 +108,12 @@ public final class TestDays360 extends TestCase {
|
||||||
* @param monthNo 1-based
|
* @param monthNo 1-based
|
||||||
* @param diffs
|
* @param diffs
|
||||||
*/
|
*/
|
||||||
private static void confirmMonthBoundary(boolean method, int monthNo, int...diffs) {
|
private static void confirmMonthBoundary(boolean method, int year, int monthNo, int...diffs) {
|
||||||
Date firstDayOfNextMonth = makeDate(2001, monthNo+1, 1);
|
Date firstDayOfNextMonth = makeDate(year, monthNo+1, 1);
|
||||||
Date secondArg = decrementDay(firstDayOfNextMonth);
|
Date secondArg = decrementDay(firstDayOfNextMonth);
|
||||||
Date firstArg = secondArg;
|
Date firstArg = secondArg;
|
||||||
|
|
||||||
for (int i = 0; i < diffs.length; i++) {
|
for (int expResult : diffs) {
|
||||||
int expResult = diffs[i];
|
|
||||||
confirm(expResult, firstArg, secondArg, method);
|
confirm(expResult, firstArg, secondArg, method);
|
||||||
firstArg = decrementDay(firstArg);
|
firstArg = decrementDay(firstArg);
|
||||||
}
|
}
|
||||||
|
@ -133,22 +128,17 @@ public final class TestDays360 extends TestCase {
|
||||||
} else {
|
} else {
|
||||||
ve = invokeDays360(convert(firstArg), convert(secondArg));
|
ve = invokeDays360(convert(firstArg), convert(secondArg));
|
||||||
}
|
}
|
||||||
if (ve instanceof NumberEval) {
|
assertTrue("wrong return type (" + ve.getClass().getName() + ")", ve instanceof NumberEval);
|
||||||
|
|
||||||
NumberEval numberEval = (NumberEval) ve;
|
NumberEval numberEval = (NumberEval) ve;
|
||||||
if (numberEval.getNumberValue() != expResult) {
|
String err = String.format(Locale.ROOT, "days360(%tF,%tF,%b) wrong result", firstArg, secondArg, method);
|
||||||
throw new AssertionFailedError(fmt(firstArg) + " " + fmt(secondArg) + " " + method +
|
assertEquals(err, expResult, numberEval.getNumberValue(), 0);
|
||||||
" wrong result got (" + numberEval.getNumberValue()
|
|
||||||
+ ") but expected (" + expResult + ")");
|
|
||||||
}
|
|
||||||
// System.err.println(fmt(firstArg) + " " + fmt(secondArg) + " " + method + " success got (" + expResult + ")");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new AssertionFailedError("wrong return type (" + ve.getClass().getName() + ")");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ValueEval invokeDays360(ValueEval...args) {
|
private static ValueEval invokeDays360(ValueEval...args) {
|
||||||
return new Days360().evaluate(args, -1, -1);
|
return new Days360().evaluate(args, -1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static NumberEval convert(Date d) {
|
private static NumberEval convert(Date d) {
|
||||||
return new NumberEval(HSSFDateUtil.getExcelDate(d));
|
return new NumberEval(HSSFDateUtil.getExcelDate(d));
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,40 +22,34 @@ import org.apache.poi.ss.formula.TestSheetNameFormatter;
|
||||||
import org.apache.poi.ss.formula.eval.AllFormulaEvalTests;
|
import org.apache.poi.ss.formula.eval.AllFormulaEvalTests;
|
||||||
import org.apache.poi.ss.formula.function.AllFormulaFunctionTests;
|
import org.apache.poi.ss.formula.function.AllFormulaFunctionTests;
|
||||||
import org.apache.poi.ss.formula.functions.AllIndividualFunctionEvaluationTests;
|
import org.apache.poi.ss.formula.functions.AllIndividualFunctionEvaluationTests;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
import junit.framework.Test;
|
import org.junit.runners.Suite;
|
||||||
import junit.framework.TestSuite;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collects all tests for <tt>org.apache.poi.hssf.record.formula</tt>.
|
* Collects all tests for <tt>org.apache.poi.hssf.record.formula</tt>.
|
||||||
*
|
|
||||||
* @author Josh Micich
|
|
||||||
*/
|
*/
|
||||||
public final class AllFormulaTests {
|
@RunWith(Suite.class)
|
||||||
|
@Suite.SuiteClasses({
|
||||||
public static Test suite() {
|
AllFormulaEvalTests.class,
|
||||||
TestSuite result = new TestSuite(AllFormulaTests.class.getName());
|
AllFormulaFunctionTests.class,
|
||||||
result.addTest(AllFormulaEvalTests.suite());
|
AllIndividualFunctionEvaluationTests.class,
|
||||||
result.addTest(AllFormulaFunctionTests.suite());
|
TestArea3DPtg.class,
|
||||||
result.addTest(AllIndividualFunctionEvaluationTests.suite());
|
TestAreaErrPtg.class,
|
||||||
|
TestAreaPtg.class,
|
||||||
result.addTestSuite(TestArea3DPtg.class);
|
TestArrayPtg.class,
|
||||||
result.addTestSuite(TestAreaErrPtg.class);
|
TestAttrPtg.class,
|
||||||
result.addTestSuite(TestAreaPtg.class);
|
TestErrPtg.class,
|
||||||
result.addTestSuite(TestArrayPtg.class);
|
TestExternalFunctionFormulas.class,
|
||||||
result.addTestSuite(TestAttrPtg.class);
|
TestFormulaShifter.class,
|
||||||
result.addTestSuite(TestErrPtg.class);
|
TestFuncPtg.class,
|
||||||
result.addTestSuite(TestExternalFunctionFormulas.class);
|
TestFuncVarPtg.class,
|
||||||
result.addTestSuite(TestFormulaShifter.class);
|
TestIntersectionPtg.class,
|
||||||
result.addTestSuite(TestFuncPtg.class);
|
TestPercentPtg.class,
|
||||||
result.addTestSuite(TestFuncVarPtg.class);
|
TestRangePtg.class,
|
||||||
result.addTestSuite(TestIntersectionPtg.class);
|
TestRef3DPtg.class,
|
||||||
result.addTestSuite(TestPercentPtg.class);
|
TestReferencePtg.class,
|
||||||
result.addTestSuite(TestRangePtg.class);
|
TestSheetNameFormatter.class,
|
||||||
result.addTestSuite(TestRef3DPtg.class);
|
TestUnionPtg.class,
|
||||||
result.addTestSuite(TestReferencePtg.class);
|
})
|
||||||
result.addTestSuite(TestSheetNameFormatter.class);
|
public class AllFormulaTests {
|
||||||
result.addTestSuite(TestUnionPtg.class);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ package org.apache.poi.ss.usermodel;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import junit.framework.AssertionFailedError;
|
import junit.framework.AssertionFailedError;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
@ -78,7 +80,7 @@ public abstract class BaseTestCell extends TestCase {
|
||||||
assertProhibitedValueAccess(cell, Cell.CELL_TYPE_NUMERIC, Cell.CELL_TYPE_BOOLEAN,
|
assertProhibitedValueAccess(cell, Cell.CELL_TYPE_NUMERIC, Cell.CELL_TYPE_BOOLEAN,
|
||||||
Cell.CELL_TYPE_FORMULA, Cell.CELL_TYPE_ERROR);
|
Cell.CELL_TYPE_FORMULA, Cell.CELL_TYPE_ERROR);
|
||||||
|
|
||||||
Calendar c = Calendar.getInstance();
|
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ROOT);
|
||||||
c.setTimeInMillis(123456789);
|
c.setTimeInMillis(123456789);
|
||||||
cell.setCellValue(c.getTime());
|
cell.setCellValue(c.getTime());
|
||||||
assertEquals(c.getTime().getTime(), cell.getDateCellValue().getTime());
|
assertEquals(c.getTime().getTime(), cell.getDateCellValue().getTime());
|
||||||
|
|
Loading…
Reference in New Issue