package org.apache.poi.ss.formula.functions;
import java.util.Calendar;
-import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
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
* 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 {
/**
}
private static double evaluate(double d0, double d1, boolean method) {
- Calendar startingDate = getStartingDate(d0);
- Calendar endingDate = getEndingDateAccordingToStartingDate(d1, startingDate);
- long startingDay = startingDate.get(Calendar.MONTH) * 30 + startingDate.get(Calendar.DAY_OF_MONTH);
- long endingDay = (endingDate.get(Calendar.YEAR) - startingDate.get(Calendar.YEAR)) * 360
- + endingDate.get(Calendar.MONTH) * 30 + endingDate.get(Calendar.DAY_OF_MONTH);
- return endingDay - startingDay;
+ Calendar realStart = getDate(d0);
+ Calendar realEnd = getDate(d1);
+ int startingDate[] = getStartingDate(realStart, method);
+ int endingDate[] = getEndingDate(realEnd, realStart, method);
+
+ return
+ (endingDate[0]*360+endingDate[1]*30+endingDate[2])-
+ (startingDate[0]*360+startingDate[1]*30+startingDate[2]);
}
private static Calendar getDate(double date) {
- Calendar processedDate = new GregorianCalendar(DEFAULT_TIMEZONE, Locale.ROOT);
- processedDate.setTime(DateUtil.getJavaDate(date, false));
+ Calendar processedDate = Calendar.getInstance(DEFAULT_TIMEZONE, Locale.ROOT);
+ processedDate.setTime(DateUtil.getJavaDate(date, false, DEFAULT_TIMEZONE));
return processedDate;
}
- private static Calendar getStartingDate(double date) {
- Calendar startingDate = getDate(date);
- if (isLastDayOfMonth(startingDate)) {
- startingDate.set(Calendar.DAY_OF_MONTH, 30);
- }
- return startingDate;
+ private static int[] getStartingDate(Calendar realStart, boolean method) {
+ Calendar d = realStart;
+ int yyyy = d.get(Calendar.YEAR);
+ int mm = d.get(Calendar.MONTH);
+ int dd = Math.min(30, d.get(Calendar.DAY_OF_MONTH));
+
+ if (method == false && isLastDayOfMonth(d)) dd = 30;
+
+ return new int[]{yyyy,mm,dd};
}
- private static Calendar getEndingDateAccordingToStartingDate(double date, Calendar startingDate) {
- Calendar endingDate = getDate(date);
- endingDate.setTime(DateUtil.getJavaDate(date, false));
- if (isLastDayOfMonth(endingDate)) {
- if (startingDate.get(Calendar.DATE) < 30) {
- endingDate = getFirstDayOfNextMonth(endingDate);
+ private static int[] getEndingDate(Calendar realEnd, Calendar realStart, boolean method) {
+ Calendar d = realEnd;
+ int yyyy = d.get(Calendar.YEAR);
+ int mm = d.get(Calendar.MONTH);
+ int dd = Math.min(30, d.get(Calendar.DAY_OF_MONTH));
+
+ 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) {
- Calendar clone = (Calendar) date.clone();
- clone.add(java.util.Calendar.MONTH, 1);
- clone.add(java.util.Calendar.DAY_OF_MONTH, -1);
- 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;
+ int dayOfMonth = date.get(Calendar.DAY_OF_MONTH);
+ int lastDayOfMonth = date.getActualMaximum(Calendar.DAY_OF_MONTH);
+ return (dayOfMonth == lastDayOfMonth);
}
}
import java.util.Calendar;
import java.util.Date;
-import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
import java.util.regex.Pattern;
* @param use1904windowing Should 1900 or 1904 date windowing be used?
*/
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
return internalGetExcelDate(calStart, use1904windowing);
}
int millisecondsInDay = (int)((date - wholeDays) * DAY_MILLISECONDS + 0.5);
Calendar calendar;
if (timeZone != null) {
- calendar = new GregorianCalendar(timeZone, Locale.ROOT);
+ calendar = Calendar.getInstance(timeZone, Locale.ROOT);
} 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);
return calendar;
};
private static ThreadLocal<String> lastFormatString = new ThreadLocal<String>();
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) {
String cachedFormatString = lastFormatString.get();
lastFormatString.set(formatString);
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
int month = parseInt(monthStr, "month", 1, 12);
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(Calendar.MILLISECOND, 0);
return cal.getTime();
import java.util.Date;
import java.util.Iterator;
import java.util.List;
+import java.util.TimeZone;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.hssf.HSSFITestDataProvider;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
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.Name;
import org.apache.poi.ss.usermodel.Row;
*/
@Test
public void bug46664() throws Exception {
- HSSFWorkbook wb = new HSSFWorkbook();
- HSSFSheet sheet = wb.createSheet("new_sheet");
+ HSSFWorkbook wb1 = new HSSFWorkbook();
+ HSSFSheet sheet = wb1.createSheet("new_sheet");
HSSFRow row = sheet.createRow((short)0);
row.createCell(0).setCellValue(new HSSFRichTextString("Column A"));
row.createCell(1).setCellValue(new HSSFRichTextString("Column B"));
row.createCell(5).setCellValue(new HSSFRichTextString("Column F"));
//set print area from column a to column c (on first row)
- wb.setPrintArea(
+ wb1.setPrintArea(
0, //sheet index
0, //start column
2, //end column
0 //end row
);
- wb = writeOutAndReadBack(wb);
+ HSSFWorkbook wb2 = writeOutAndReadBack(wb1);
+ wb1.close();
// Ensure the tab index
TabIdRecord tr = null;
- for(Record r : wb.getWorkbook().getRecords()) {
+ for(Record r : wb2.getWorkbook().getRecords()) {
if(r instanceof TabIdRecord) {
tr = (TabIdRecord)r;
}
assertEquals(0, tr._tabids[0]);
// Ensure the print setup
- assertEquals("new_sheet!$A$1:$C$1", wb.getPrintArea(0));
- assertEquals("new_sheet!$A$1:$C$1", wb.getName("Print_Area").getRefersToFormula());
+ assertEquals("new_sheet!$A$1:$C$1", wb2.getPrintArea(0));
+ assertEquals("new_sheet!$A$1:$C$1", wb2.getName("Print_Area").getRefersToFormula());
// Needs reference not value
- NameRecord nr = wb.getWorkbook().getNameRecord(
- wb.getNameIndex("Print_Area")
+ NameRecord nr = wb2.getWorkbook().getNameRecord(
+ wb2.getNameIndex("Print_Area")
);
assertEquals("Print_Area", nr.getNameText());
assertEquals(1, nr.getNameDefinition().length);
assertEquals(
"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());
+ wb2.close();
}
/**
*/
@Test
public void bug49689() throws Exception {
- HSSFWorkbook wb = new HSSFWorkbook();
- HSSFSheet s = wb.createSheet("Test");
+ HSSFWorkbook wb1 = new HSSFWorkbook();
+ HSSFSheet s = wb1.createSheet("Test");
HSSFRow r = s.createRow(0);
HSSFCell c = r.createCell(0);
- HSSFCellStyle cs1 = wb.createCellStyle();
- HSSFCellStyle cs2 = wb.createCellStyle();
- HSSFCellStyle cs3 = wb.createCellStyle();
+ HSSFCellStyle cs1 = wb1.createCellStyle();
+ HSSFCellStyle cs2 = wb1.createCellStyle();
+ HSSFCellStyle cs3 = wb1.createCellStyle();
assertEquals(21, cs1.getIndex());
cs1.setUserStyleName("Testing");
c.setCellStyle(cs1);
// Write out and read back
- wb = writeOutAndReadBack(wb);
+ HSSFWorkbook wb2 = writeOutAndReadBack(wb1);
// Re-check
- assertEquals("Testing", wb.getCellStyleAt((short)21).getUserStyleName());
- assertEquals("Testing 2", wb.getCellStyleAt((short)22).getUserStyleName());
- assertEquals("Testing 3", wb.getCellStyleAt((short)23).getUserStyleName());
+ assertEquals("Testing", wb2.getCellStyleAt((short)21).getUserStyleName());
+ assertEquals("Testing 2", wb2.getCellStyleAt((short)22).getUserStyleName());
+ assertEquals("Testing 3", wb2.getCellStyleAt((short)23).getUserStyleName());
+
+ wb2.close();
}
@Test
@Test
public void bug48968() throws Exception {
- HSSFWorkbook wb = openSample("48968.xls");
- assertEquals(1, wb.getNumberOfSheets());
-
- DataFormatter fmt = new DataFormatter();
-
- // Check the dates
- HSSFSheet s = wb.getSheetAt(0);
- Cell cell_d20110325 = s.getRow(0).getCell(0);
- Cell cell_d19000102 = s.getRow(11).getCell(0);
- Cell cell_d19000100 = s.getRow(21).getCell(0);
- assertEquals(s.getRow(0).getCell(3).getStringCellValue(), fmt.formatCellValue(cell_d20110325));
- assertEquals(s.getRow(11).getCell(3).getStringCellValue(), fmt.formatCellValue(cell_d19000102));
- // There is no such thing as 00/01/1900...
- assertEquals("00/01/1900 06:14:24", s.getRow(21).getCell(3).getStringCellValue());
- assertEquals("31/12/1899 06:14:24", fmt.formatCellValue(cell_d19000100));
-
- // Check the cached values
- assertEquals("HOUR(A1)", s.getRow(5).getCell(0).getCellFormula());
- assertEquals(11.0, s.getRow(5).getCell(0).getNumericCellValue(), 0);
- assertEquals("MINUTE(A1)", s.getRow(6).getCell(0).getCellFormula());
- assertEquals(39.0, s.getRow(6).getCell(0).getNumericCellValue(), 0);
- assertEquals("SECOND(A1)", s.getRow(7).getCell(0).getCellFormula());
- assertEquals(54.0, s.getRow(7).getCell(0).getNumericCellValue(), 0);
-
- // Re-evaulate and check
- HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
- assertEquals("HOUR(A1)", s.getRow(5).getCell(0).getCellFormula());
- assertEquals(11.0, s.getRow(5).getCell(0).getNumericCellValue(), 0);
- assertEquals("MINUTE(A1)", s.getRow(6).getCell(0).getCellFormula());
- assertEquals(39.0, s.getRow(6).getCell(0).getNumericCellValue(), 0);
- assertEquals("SECOND(A1)", s.getRow(7).getCell(0).getCellFormula());
- assertEquals(54.0, s.getRow(7).getCell(0).getNumericCellValue(), 0);
-
- // Push the time forward a bit and check
- double date = s.getRow(0).getCell(0).getNumericCellValue();
- s.getRow(0).getCell(0).setCellValue(date + 1.26);
-
- HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
- assertEquals("HOUR(A1)", s.getRow(5).getCell(0).getCellFormula());
- assertEquals(11.0+6.0, s.getRow(5).getCell(0).getNumericCellValue(), 0);
- assertEquals("MINUTE(A1)", s.getRow(6).getCell(0).getCellFormula());
- assertEquals(39.0+14.0+1, s.getRow(6).getCell(0).getNumericCellValue(), 0);
- assertEquals("SECOND(A1)", s.getRow(7).getCell(0).getCellFormula());
- assertEquals(54.0+24.0-60, s.getRow(7).getCell(0).getNumericCellValue(), 0);
+ TimeZone tz = DateUtil.getUserTimeZone();
+ try {
+ DateUtil.setUserTimeZone(TimeZone.getTimeZone("CET"));
+
+ HSSFWorkbook wb = openSample("48968.xls");
+ assertEquals(1, wb.getNumberOfSheets());
+
+ DataFormatter fmt = new DataFormatter();
+
+ // Check the dates
+ HSSFSheet s = wb.getSheetAt(0);
+ Cell cell_d20110325 = s.getRow(0).getCell(0);
+ Cell cell_d19000102 = s.getRow(11).getCell(0);
+ Cell cell_d19000100 = s.getRow(21).getCell(0);
+ assertEquals(s.getRow(0).getCell(3).getStringCellValue(), fmt.formatCellValue(cell_d20110325));
+ assertEquals(s.getRow(11).getCell(3).getStringCellValue(), fmt.formatCellValue(cell_d19000102));
+ // There is no such thing as 00/01/1900...
+ assertEquals("00/01/1900 06:14:24", s.getRow(21).getCell(3).getStringCellValue());
+ assertEquals("31/12/1899 06:14:24", fmt.formatCellValue(cell_d19000100));
+
+ // Check the cached values
+ assertEquals("HOUR(A1)", s.getRow(5).getCell(0).getCellFormula());
+ assertEquals(11.0, s.getRow(5).getCell(0).getNumericCellValue(), 0);
+ assertEquals("MINUTE(A1)", s.getRow(6).getCell(0).getCellFormula());
+ assertEquals(39.0, s.getRow(6).getCell(0).getNumericCellValue(), 0);
+ assertEquals("SECOND(A1)", s.getRow(7).getCell(0).getCellFormula());
+ assertEquals(54.0, s.getRow(7).getCell(0).getNumericCellValue(), 0);
+
+ // Re-evaulate and check
+ HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
+ assertEquals("HOUR(A1)", s.getRow(5).getCell(0).getCellFormula());
+ assertEquals(11.0, s.getRow(5).getCell(0).getNumericCellValue(), 0);
+ assertEquals("MINUTE(A1)", s.getRow(6).getCell(0).getCellFormula());
+ assertEquals(39.0, s.getRow(6).getCell(0).getNumericCellValue(), 0);
+ assertEquals("SECOND(A1)", s.getRow(7).getCell(0).getCellFormula());
+ assertEquals(54.0, s.getRow(7).getCell(0).getNumericCellValue(), 0);
+
+ // Push the time forward a bit and check
+ double date = s.getRow(0).getCell(0).getNumericCellValue();
+ s.getRow(0).getCell(0).setCellValue(date + 1.26);
+
+ HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
+ assertEquals("HOUR(A1)", s.getRow(5).getCell(0).getCellFormula());
+ assertEquals(11.0+6.0, s.getRow(5).getCell(0).getNumericCellValue(), 0);
+ assertEquals("MINUTE(A1)", s.getRow(6).getCell(0).getCellFormula());
+ assertEquals(39.0+14.0+1, s.getRow(6).getCell(0).getNumericCellValue(), 0);
+ assertEquals("SECOND(A1)", s.getRow(7).getCell(0).getCellFormula());
+ 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
@Test
public void bug53432() throws IOException{
- Workbook wb = new HSSFWorkbook(); //or new HSSFWorkbook();
- wb.addPicture(new byte[]{123,22}, Workbook.PICTURE_TYPE_JPEG);
- assertEquals(wb.getAllPictures().size(), 1);
- wb.close();
-
- wb.close();
- wb = new HSSFWorkbook();
-
- wb = writeOutAndReadBack((HSSFWorkbook) wb);
- assertEquals(wb.getAllPictures().size(), 0);
- wb.addPicture(new byte[]{123,22}, Workbook.PICTURE_TYPE_JPEG);
- assertEquals(wb.getAllPictures().size(), 1);
-
- wb = writeOutAndReadBack((HSSFWorkbook) wb);
- assertEquals(wb.getAllPictures().size(), 1);
+ Workbook wb1 = new HSSFWorkbook(); //or new HSSFWorkbook();
+ wb1.addPicture(new byte[]{123,22}, Workbook.PICTURE_TYPE_JPEG);
+ assertEquals(wb1.getAllPictures().size(), 1);
+ wb1.close();
+
+ wb1.close();
+ wb1 = new HSSFWorkbook();
+
+ Workbook wb2 = writeOutAndReadBack((HSSFWorkbook) wb1);
+ wb1.close();
+ assertEquals(wb2.getAllPictures().size(), 0);
+ wb2.addPicture(new byte[]{123,22}, Workbook.PICTURE_TYPE_JPEG);
+ assertEquals(wb2.getAllPictures().size(), 1);
+
+ Workbook wb3 = writeOutAndReadBack((HSSFWorkbook) wb2);
+ wb2.close();
+ assertEquals(wb3.getAllPictures().size(), 1);
- wb.close();
+ wb3.close();
}
@Test
@Test
public void bug56325() throws IOException {
- HSSFWorkbook wb;
+ HSSFWorkbook wb1;
File file = HSSFTestDataSamples.getSampleFile("56325.xls");
InputStream stream = new FileInputStream(file);
try {
POIFSFileSystem fs = new POIFSFileSystem(stream);
- wb = new HSSFWorkbook(fs);
+ wb1 = new HSSFWorkbook(fs);
} finally {
stream.close();
}
- assertEquals(3, wb.getNumberOfSheets());
- wb.removeSheetAt(0);
- assertEquals(2, wb.getNumberOfSheets());
+ assertEquals(3, wb1.getNumberOfSheets());
+ wb1.removeSheetAt(0);
+ assertEquals(2, wb1.getNumberOfSheets());
- wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
- assertEquals(2, wb.getNumberOfSheets());
- wb.removeSheetAt(0);
- assertEquals(1, wb.getNumberOfSheets());
- wb.removeSheetAt(0);
- assertEquals(0, wb.getNumberOfSheets());
+ HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1);
+ wb1.close();
+ assertEquals(2, wb2.getNumberOfSheets());
+ wb2.removeSheetAt(0);
+ assertEquals(1, wb2.getNumberOfSheets());
+ wb2.removeSheetAt(0);
+ assertEquals(0, wb2.getNumberOfSheets());
- wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
- assertEquals(0, wb.getNumberOfSheets());
+ HSSFWorkbook wb3 = HSSFTestDataSamples.writeOutAndReadBack(wb2);
+ wb2.close();
+
+ assertEquals(0, wb3.getNumberOfSheets());
+ wb3.close();
}
@Test
package org.apache.poi.hssf.usermodel;
import java.io.IOException;
+import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
-
-import junit.framework.AssertionFailedError;
+import java.util.Locale;
+import java.util.TimeZone;
import org.apache.poi.hssf.HSSFITestDataProvider;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
+import junit.framework.AssertionFailedError;
+
/**
* Tests various functionality having to do with {@link HSSFCell}. For instance support for
* particular datatypes, etc.
* but there's a separate unit test for that.
*/
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();
// first check a file with 1900 Date Windowing
package org.apache.poi.ss.formula.eval;
-import junit.framework.Test;
-import junit.framework.TestSuite;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
/**
* 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 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;
- }
}
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.util.Collection;
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.ss.formula.functions.TestMathX;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
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.CellValue;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.util.POILogFactory;
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/>
*
* @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 class Result {
private static void confirmExpectedResult(String msg, Cell expected, CellValue actual) {
- if (expected == null) {
- throw new AssertionFailedError(msg + " - Bad setup data expected value is null");
- }
- if(actual == null) {
- throw new AssertionFailedError(msg + " - actual value was null");
- }
+ assertNotNull(msg + " - Bad setup data expected value is null", expected);
+ assertNotNull(msg + " - actual value was null", actual);
switch (expected.getCellType()) {
case Cell.CELL_TYPE_BLANK:
assertEquals(msg, ErrorEval.getText(expected.getErrorCellValue()), ErrorEval.getText(actual.getErrorValue()));
break;
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:
assertEquals(msg, Cell.CELL_TYPE_NUMERIC, actual.getCellType());
TestMathX.assertEquals(msg, expected.getNumericCellValue(), actual.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR);
}
}
-
+ @Before
protected void setUp() {
if (workbook == null) {
workbook = HSSFTestDataSamples.openSampleWorkbook(SS.FILENAME);
_evaluationSuccessCount = 0;
}
+ @Test
public void testFunctionsFromTestSpreadsheet() {
processFunctionGroup(SS.START_OPERATORS_ROW_INDEX, null);
String successMsg = "There were "
+ _evaluationSuccessCount + " successful evaluation(s) and "
+ _functionSuccessCount + " function(s) without error";
- if(_functionFailureCount > 0) {
- String msg = _functionFailureCount + " function(s) failed in "
- + _evaluationFailureCount + " evaluation(s). " + successMsg;
- throw new AssertionFailedError(msg);
- }
+ String msg = _functionFailureCount + " function(s) failed in "
+ + _evaluationFailureCount + " evaluation(s). " + successMsg;
+ assertEquals(msg, _functionFailureCount, 0);
logger.log(POILogger.INFO, getClass().getName() + ": " + successMsg);
}
while (true) {
Row r = sheet.getRow(rowIndex);
String targetFunctionName = getTargetFunctionName(r);
- if(targetFunctionName == null) {
- throw new AssertionFailedError("Test spreadsheet cell empty on row ("
- + (rowIndex+1) + "). Expected function name or '"
- + SS.FUNCTION_NAMES_END_SENTINEL + "'");
- }
+ assertNotNull("Test spreadsheet cell empty on row ("
+ + (rowIndex+1) + "). Expected function name or '"
+ + SS.FUNCTION_NAMES_END_SENTINEL + "'", targetFunctionName);
if(targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) {
// found end of functions list
break;
// expected results are on the row below
Row expectedValuesRow = sheet.getRow(rowIndex + 1);
- if(expectedValuesRow == null) {
- int missingRowNum = rowIndex + 2; //+1 for 1-based, +1 for next row
- throw new AssertionFailedError("Missing expected values row for function '"
- + targetFunctionName + " (row " + missingRowNum + ")");
- }
+ int missingRowNum = rowIndex + 2; //+1 for 1-based, +1 for next row
+ assertNotNull("Missing expected values row for function '"
+ + targetFunctionName + " (row " + missingRowNum + ")", expectedValuesRow);
switch(processFunctionRow(evaluator, targetFunctionName, r, expectedValuesRow)) {
case Result.ALL_EVALUATIONS_SUCCEEDED: _functionSuccessCount++; break;
case Result.SOME_EVALUATIONS_FAILED: _functionFailureCount++; break;
package org.apache.poi.ss.formula.functions;
-import junit.framework.Test;
-import junit.framework.TestSuite;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
/**
* Direct tests for all implementors of <code>Function</code>.
- *
- * @author Josh Micich
*/
-public final class AllIndividualFunctionEvaluationTests {
-
- public static Test suite() {
- TestSuite result = new TestSuite(AllIndividualFunctionEvaluationTests.class.getName());
- result.addTestSuite(TestAverage.class);
- result.addTestSuite(TestCountFuncs.class);
- result.addTestSuite(TestDate.class);
- result.addTestSuite(TestDays360.class);
- result.addTestSuite(TestFinanceLib.class);
- result.addTestSuite(TestFind.class);
- result.addTestSuite(TestIndex.class);
- result.addTestSuite(TestIndexFunctionFromSpreadsheet.class);
- result.addTestSuite(TestIndirect.class);
- result.addTestSuite(TestIsBlank.class);
- result.addTestSuite(TestLen.class);
- result.addTestSuite(TestLookupFunctionsFromSpreadsheet.class);
- result.addTestSuite(TestMatch.class);
- result.addTestSuite(TestMathX.class);
- result.addTestSuite(TestMid.class);
- result.addTestSuite(TestNper.class);
- result.addTestSuite(TestOffset.class);
- result.addTestSuite(TestPmt.class);
- result.addTestSuite(TestRoundFuncs.class);
- result.addTestSuite(TestRowCol.class);
- result.addTestSuite(TestStatsLib.class);
- result.addTestSuite(TestSubtotal.class);
- result.addTestSuite(TestSumif.class);
- result.addTestSuite(TestSumproduct.class);
- result.addTestSuite(TestText.class);
- result.addTestSuite(TestTFunc.class);
- result.addTestSuite(TestTime.class);
- result.addTestSuite(TestTrim.class);
- result.addTestSuite(TestTrunc.class);
- result.addTestSuite(TestValue.class);
- result.addTestSuite(TestXYNumericFunction.class);
- result.addTestSuite(TestAddress.class);
- result.addTestSuite(TestClean.class);
- return result;
- }
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ TestAverage.class,
+ TestCountFuncs.class,
+ TestDate.class,
+ TestDays360.class,
+ TestFinanceLib.class,
+ TestFind.class,
+ TestIndex.class,
+ TestIndexFunctionFromSpreadsheet.class,
+ TestIndirect.class,
+ TestIsBlank.class,
+ TestLen.class,
+ TestLookupFunctionsFromSpreadsheet.class,
+ TestMatch.class,
+ TestMathX.class,
+ TestMid.class,
+ TestNper.class,
+ TestOffset.class,
+ TestPmt.class,
+ TestRoundFuncs.class,
+ TestRowCol.class,
+ TestStatsLib.class,
+ TestSubtotal.class,
+ TestSumif.class,
+ TestSumproduct.class,
+ TestText.class,
+ TestTFunc.class,
+ TestTime.class,
+ TestTrim.class,
+ TestTrunc.class,
+ TestValue.class,
+ TestXYNumericFunction.class,
+ TestAddress.class,
+ TestClean.class
+})
+public class AllIndividualFunctionEvaluationTests {
}
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.Date;
-import java.util.GregorianCalendar;
import java.util.Locale;
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
+import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.formula.eval.BoolEval;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.ValueEval;
-import org.apache.poi.hssf.usermodel.HSSFDateUtil;
+import org.junit.Test;
-/**
- * @author Josh Micich
- */
-public final class TestDays360 extends TestCase {
+public final class TestDays360 {
/**
* @param month 1-based
*/
private static Date makeDate(int year, int month, int day) {
-
- Calendar cal = new GregorianCalendar(year, month-1, day, 0, 0, 0);
+ Calendar cal = Calendar.getInstance(Locale.ROOT);
+ cal.set(year, month-1, day, 0, 0, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
+
private static Date decrementDay(Date d) {
- Calendar c = new GregorianCalendar(Locale.ROOT);
- c.setTimeInMillis(d.getTime());
+ Calendar c = (Calendar)d.clone();
c.add(Calendar.DAY_OF_MONTH, -1);
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() {
confirm(120, 2009, 1, 15, 2009, 5, 15);
confirm(158, 2009, 1, 26, 2009, 7, 4);
// longer time spans
confirm(562, 2008, 8, 11, 2010, 3, 3);
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) {
confirm(expResult, makeDate(y1, m1, d1), makeDate(y2, m2, d2), 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
* is the last day of the month that does <em>not</em> have 30 days.
*/
- public void DISABLED_testMonthBoundaries() {
+ @Test
+ public void testMonthBoundaries() {
// jan
- confirmMonthBoundary(false, 1, 0, 0, 2, 3, 4);
- confirmMonthBoundary(true, 1, 0, 0, 1, 3, 4);
+ confirmMonthBoundary(false, 2001, 1, 0, 0, 2, 3, 4);
+ confirmMonthBoundary(true, 2001, 1, 0, 0, 1, 2, 3);
// feb
- confirmMonthBoundary(false, 2,-2, 1, 2, 3, 4);
- confirmMonthBoundary(true, 2, 0, 1, 2, 3, 4);
+ confirmMonthBoundary(false, 2001, 2,-2, 1, 2, 3, 4);
+ confirmMonthBoundary(true, 2001, 2, 0, 1, 2, 3, 4);
// mar
- confirmMonthBoundary(false, 3, 0, 0, 2, 3, 4);
- confirmMonthBoundary(true, 3, 0, 0, 1, 3, 4);
+ confirmMonthBoundary(false, 2001, 3, 0, 0, 2, 3, 4);
+ confirmMonthBoundary(true, 2001, 3, 0, 0, 1, 2, 3);
// apr
- confirmMonthBoundary(false, 4, 0, 1, 2, 3, 4);
- confirmMonthBoundary(true, 4, 0, 1, 2, 3, 4);
+ confirmMonthBoundary(false, 2001, 4, 0, 1, 2, 3, 4);
+ confirmMonthBoundary(true, 2001, 4, 0, 1, 2, 3, 4);
// may
- confirmMonthBoundary(false, 5, 0, 0, 2, 3, 4);
- confirmMonthBoundary(true, 5, 0, 0, 1, 3, 4);
+ confirmMonthBoundary(false, 2001, 5, 0, 0, 2, 3, 4);
+ confirmMonthBoundary(true, 2001, 5, 0, 0, 1, 2, 3);
// jun
- confirmMonthBoundary(false, 6, 0, 1, 2, 3, 4);
- confirmMonthBoundary(true, 6, 0, 1, 2, 3, 4);
- // etc...
+ confirmMonthBoundary(false, 2001, 6, 0, 1, 2, 3, 4);
+ confirmMonthBoundary(true, 2001, 6, 0, 1, 2, 3, 4);
+ // leap year
+ confirmMonthBoundary(false, 2012, 2, -1, 1, 2, 3, 4);
+ confirmMonthBoundary(true, 2012, 2, 0, 1, 2, 3, 4);
}
* @param monthNo 1-based
* @param diffs
*/
- private static void confirmMonthBoundary(boolean method, int monthNo, int...diffs) {
- Date firstDayOfNextMonth = makeDate(2001, monthNo+1, 1);
+ private static void confirmMonthBoundary(boolean method, int year, int monthNo, int...diffs) {
+ Date firstDayOfNextMonth = makeDate(year, monthNo+1, 1);
Date secondArg = decrementDay(firstDayOfNextMonth);
Date firstArg = secondArg;
- for (int i = 0; i < diffs.length; i++) {
- int expResult = diffs[i];
+ for (int expResult : diffs) {
confirm(expResult, firstArg, secondArg, method);
firstArg = decrementDay(firstArg);
}
} else {
ve = invokeDays360(convert(firstArg), convert(secondArg));
}
- if (ve instanceof NumberEval) {
-
- NumberEval numberEval = (NumberEval) ve;
- if (numberEval.getNumberValue() != expResult) {
- throw new AssertionFailedError(fmt(firstArg) + " " + fmt(secondArg) + " " + method +
- " 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() + ")");
+ assertTrue("wrong return type (" + ve.getClass().getName() + ")", ve instanceof NumberEval);
+
+ NumberEval numberEval = (NumberEval) ve;
+ String err = String.format(Locale.ROOT, "days360(%tF,%tF,%b) wrong result", firstArg, secondArg, method);
+ assertEquals(err, expResult, numberEval.getNumberValue(), 0);
}
+
private static ValueEval invokeDays360(ValueEval...args) {
return new Days360().evaluate(args, -1, -1);
}
+
private static NumberEval convert(Date d) {
return new NumberEval(HSSFDateUtil.getExcelDate(d));
}
import org.apache.poi.ss.formula.eval.AllFormulaEvalTests;
import org.apache.poi.ss.formula.function.AllFormulaFunctionTests;
import org.apache.poi.ss.formula.functions.AllIndividualFunctionEvaluationTests;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
/**
* Collects all tests for <tt>org.apache.poi.hssf.record.formula</tt>.
- *
- * @author Josh Micich
*/
-public final class AllFormulaTests {
-
- public static Test suite() {
- TestSuite result = new TestSuite(AllFormulaTests.class.getName());
- result.addTest(AllFormulaEvalTests.suite());
- result.addTest(AllFormulaFunctionTests.suite());
- result.addTest(AllIndividualFunctionEvaluationTests.suite());
-
- result.addTestSuite(TestArea3DPtg.class);
- result.addTestSuite(TestAreaErrPtg.class);
- result.addTestSuite(TestAreaPtg.class);
- result.addTestSuite(TestArrayPtg.class);
- result.addTestSuite(TestAttrPtg.class);
- result.addTestSuite(TestErrPtg.class);
- result.addTestSuite(TestExternalFunctionFormulas.class);
- result.addTestSuite(TestFormulaShifter.class);
- result.addTestSuite(TestFuncPtg.class);
- result.addTestSuite(TestFuncVarPtg.class);
- result.addTestSuite(TestIntersectionPtg.class);
- result.addTestSuite(TestPercentPtg.class);
- result.addTestSuite(TestRangePtg.class);
- result.addTestSuite(TestRef3DPtg.class);
- result.addTestSuite(TestReferencePtg.class);
- result.addTestSuite(TestSheetNameFormatter.class);
- result.addTestSuite(TestUnionPtg.class);
- return result;
- }
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ AllFormulaEvalTests.class,
+ AllFormulaFunctionTests.class,
+ AllIndividualFunctionEvaluationTests.class,
+ TestArea3DPtg.class,
+ TestAreaErrPtg.class,
+ TestAreaPtg.class,
+ TestArrayPtg.class,
+ TestAttrPtg.class,
+ TestErrPtg.class,
+ TestExternalFunctionFormulas.class,
+ TestFormulaShifter.class,
+ TestFuncPtg.class,
+ TestFuncVarPtg.class,
+ TestIntersectionPtg.class,
+ TestPercentPtg.class,
+ TestRangePtg.class,
+ TestRef3DPtg.class,
+ TestReferencePtg.class,
+ TestSheetNameFormatter.class,
+ TestUnionPtg.class,
+})
+public class AllFormulaTests {
}
import java.io.IOException;
import java.util.Calendar;
+import java.util.Locale;
+import java.util.TimeZone;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
assertProhibitedValueAccess(cell, Cell.CELL_TYPE_NUMERIC, Cell.CELL_TYPE_BOOLEAN,
Cell.CELL_TYPE_FORMULA, Cell.CELL_TYPE_ERROR);
- Calendar c = Calendar.getInstance();
+ Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ROOT);
c.setTimeInMillis(123456789);
cell.setCellValue(c.getTime());
assertEquals(c.getTime().getTime(), cell.getDateCellValue().getTime());