Patch 46410 from Steven Butler - added impl for TIME() function.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@730309 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
0e193f895b
commit
d9df585ca5
@ -37,8 +37,9 @@
|
||||
|
||||
<!-- Don't forget to update status.xml too! -->
|
||||
<release version="3.5-beta5" date="2008-??-??">
|
||||
<action dev="POI-DEVELOPERS" type="add">46410 - added implementation for TIME() function</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">46320 - added HSSFPictureData.getFormat()</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">fixed HSSFSheet.shiftRow to move hyperlinks</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">46445 fixed HSSFSheet.shiftRow to move hyperlinks</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">fixed formula parser to correctly resolve sheet-level names</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">46433 - support for shared formulas in XSSF</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">46299 - support for carriage return and line break in XWPFRun</action>
|
||||
|
@ -34,8 +34,9 @@
|
||||
<!-- Don't forget to update changes.xml too! -->
|
||||
<changes>
|
||||
<release version="3.5-beta5" date="2008-??-??">
|
||||
<action dev="POI-DEVELOPERS" type="add">46410 - added implementation for TIME() function</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">46320 - added HSSFPictureData.getFormat()</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">fixed HSSFSheet.shiftRow to move hyperlinks</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">46445 fixed HSSFSheet.shiftRow to move hyperlinks</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">fixed formula parser to correctly resolve sheet-level names</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">46433 - support for shared formulas in XSSF</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">46299 - support for carriage return and line break in XWPFRun</action>
|
||||
|
@ -1,25 +1,88 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*
|
||||
* Created on May 15, 2005
|
||||
*
|
||||
*/
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
public class Time extends NotImplementedFunction {
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
|
||||
import org.apache.poi.hssf.record.formula.eval.MissingArgEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.OperandResolver;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
|
||||
/**
|
||||
* @author Steven Butler (sebutler @ gmail dot com)
|
||||
*
|
||||
* Based on POI org.apache.hssf.record.formula.DateFunc.java
|
||||
*/
|
||||
public final class Time implements Function {
|
||||
|
||||
private static final int SECONDS_PER_MINUTE = 60;
|
||||
private static final int SECONDS_PER_HOUR = 3600;
|
||||
private static final int HOURS_PER_DAY = 24;
|
||||
private static final int SECONDS_PER_DAY = HOURS_PER_DAY * SECONDS_PER_HOUR;
|
||||
|
||||
|
||||
public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
|
||||
if (args.length != 3) {
|
||||
return ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
double result;
|
||||
|
||||
try {
|
||||
result = evaluate(evalArg(args[0]), evalArg(args[1]), evalArg(args[2]));
|
||||
} catch (EvaluationException e) {
|
||||
return e.getErrorEval();
|
||||
}
|
||||
return new NumberEval(result);
|
||||
}
|
||||
private static int evalArg(Eval arg) throws EvaluationException {
|
||||
if (arg == MissingArgEval.instance) {
|
||||
return 0;
|
||||
}
|
||||
// Excel silently truncates double values to integers
|
||||
return OperandResolver.coerceValueToInt((ValueEval) arg);
|
||||
}
|
||||
/**
|
||||
* Converts the supplied hours, minutes and seconds to an Excel time value.
|
||||
*
|
||||
*
|
||||
* @param ds array of 3 doubles containing hours, minutes and seconds.
|
||||
* Non-integer inputs are truncated to an integer before further calculation
|
||||
* of the time value.
|
||||
* @return An Excel representation of a time of day.
|
||||
* If the time value represents more than a day, the days are removed from
|
||||
* the result, leaving only the time of day component.
|
||||
* @throws org.apache.poi.hssf.record.formula.eval.EvaluationException
|
||||
* If any of the arguments are greater than 32767 or the hours
|
||||
* minutes and seconds when combined form a time value less than 0, the function
|
||||
* evaluates to an error.
|
||||
*/
|
||||
private static double evaluate(int hours, int minutes, int seconds) throws EvaluationException {
|
||||
|
||||
if (hours > 32767 || minutes > 32767 || seconds > 32767) {
|
||||
throw new EvaluationException(ErrorEval.VALUE_INVALID);
|
||||
}
|
||||
int totalSeconds = hours * SECONDS_PER_HOUR + minutes * SECONDS_PER_MINUTE + seconds;
|
||||
|
||||
if (totalSeconds < 0) {
|
||||
throw new EvaluationException(ErrorEval.VALUE_INVALID);
|
||||
}
|
||||
return (totalSeconds % SECONDS_PER_DAY) / (double)SECONDS_PER_DAY;
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ public final class AllIndividualFunctionEvaluationTests {
|
||||
result.addTestSuite(TestSumproduct.class);
|
||||
result.addTestSuite(TestStatsLib.class);
|
||||
result.addTestSuite(TestTFunc.class);
|
||||
result.addTestSuite(TestTime.class);
|
||||
result.addTestSuite(TestTrim.class);
|
||||
result.addTestSuite(TestValue.class);
|
||||
result.addTestSuite(TestXYNumericFunction.class);
|
||||
|
@ -0,0 +1,122 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
|
||||
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
|
||||
import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
|
||||
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
/**
|
||||
* Tests for {@link Time}
|
||||
*
|
||||
* @author @author Steven Butler (sebutler @ gmail dot com)
|
||||
*/
|
||||
public final class TestTime extends TestCase {
|
||||
|
||||
private static final int SECONDS_PER_MINUTE = 60;
|
||||
private static final int SECONDS_PER_HOUR = 60 * SECONDS_PER_MINUTE;
|
||||
private static final double SECONDS_PER_DAY = 24 * SECONDS_PER_HOUR;
|
||||
private HSSFCell cell11;
|
||||
private HSSFFormulaEvaluator evaluator;
|
||||
private HSSFWorkbook wb;
|
||||
private HSSFDataFormatter form;
|
||||
private HSSFCellStyle style;
|
||||
|
||||
public void setUp() {
|
||||
wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet("new sheet");
|
||||
style = wb.createCellStyle();
|
||||
HSSFDataFormat fmt = wb.createDataFormat();
|
||||
style.setDataFormat(fmt.getFormat("hh:mm:ss"));
|
||||
|
||||
cell11 = sheet.createRow(0).createCell(0);
|
||||
form = new HSSFDataFormatter();
|
||||
|
||||
evaluator = new HSSFFormulaEvaluator(wb);
|
||||
}
|
||||
|
||||
public void testSomeArgumentsMissing() {
|
||||
confirm("00:00:00", "TIME(, 0, 0)");
|
||||
confirm("12:00:00", "TIME(12, , )");
|
||||
}
|
||||
|
||||
public void testValid() {
|
||||
confirm("00:00:01", 0, 0, 1);
|
||||
confirm("00:01:00", 0, 1, 0);
|
||||
|
||||
confirm("00:00:00", 0, 0, 0);
|
||||
|
||||
confirm("01:00:00", 1, 0, 0);
|
||||
confirm("12:00:00", 12, 0, 0);
|
||||
confirm("23:00:00", 23, 0, 0);
|
||||
confirm("00:00:00", 24, 0, 0);
|
||||
confirm("01:00:00", 25, 0, 0);
|
||||
confirm("00:00:00", 48, 0, 0);
|
||||
confirm("06:00:00", 6, 0, 0);
|
||||
confirm("06:01:00", 6, 1, 0);
|
||||
confirm("06:30:00", 6, 30, 0);
|
||||
|
||||
confirm("06:59:00", 6, 59, 0);
|
||||
confirm("07:00:00", 6, 60, 0);
|
||||
confirm("07:01:00", 6, 61, 0);
|
||||
confirm("08:00:00", 6, 120, 0);
|
||||
confirm("06:00:00", 6, 1440, 0);
|
||||
confirm("18:49:00", 18, 49, 0);
|
||||
confirm("18:49:01", 18, 49, 1);
|
||||
confirm("18:49:30", 18, 49, 30);
|
||||
confirm("18:49:59", 18, 49, 59);
|
||||
confirm("18:50:00", 18, 49, 60);
|
||||
confirm("18:50:01", 18, 49, 61);
|
||||
confirm("18:50:59", 18, 49, 119);
|
||||
confirm("18:51:00", 18, 49, 120);
|
||||
confirm("03:55:07", 18, 49, 32767);
|
||||
confirm("12:08:01", 18, 32767, 61);
|
||||
confirm("07:50:01", 32767, 49, 61);
|
||||
}
|
||||
private void confirm(String expectedTimeStr, int inH, int inM, int inS) {
|
||||
confirm(expectedTimeStr, "TIME(" + inH + "," + inM + "," + inS + ")");
|
||||
}
|
||||
|
||||
private void confirm(String expectedTimeStr, String formulaText) {
|
||||
// System.out.println("=" + formulaText);
|
||||
String[] parts = Pattern.compile(":").split(expectedTimeStr);
|
||||
int expH = Integer.parseInt(parts[0]);
|
||||
int expM = Integer.parseInt(parts[1]);
|
||||
int expS = Integer.parseInt(parts[2]);
|
||||
|
||||
double expectedValue = (expH*SECONDS_PER_HOUR + expM*SECONDS_PER_MINUTE + expS)/SECONDS_PER_DAY;
|
||||
|
||||
cell11.setCellFormula(formulaText);
|
||||
cell11.setCellStyle(style);
|
||||
evaluator.clearAllCachedResultValues();
|
||||
|
||||
double actualValue = evaluator.evaluate(cell11).getNumberValue();
|
||||
assertEquals(expectedValue, actualValue, 0.0);
|
||||
|
||||
String actualText = form.formatCellValue(cell11, evaluator);
|
||||
assertEquals(expectedTimeStr, actualText);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user