/* ==================================================================== | |
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.ss.formula.functions; | |
import java.util.Calendar; | |
import java.util.Date; | |
import org.apache.poi.ss.formula.OperationEvaluationContext; | |
import org.apache.poi.ss.formula.eval.ErrorEval; | |
import org.apache.poi.ss.formula.eval.EvaluationException; | |
import org.apache.poi.ss.formula.eval.NumberEval; | |
import org.apache.poi.ss.formula.eval.ValueEval; | |
import org.apache.poi.ss.usermodel.DateUtil; | |
import org.apache.poi.util.LocaleUtil; | |
/** | |
* Implementation for the Excel EOMONTH() function.<p/> | |
* <p/> | |
* EOMONTH() returns the date of the last day of a month..<p/> | |
* <p/> | |
* <b>Syntax</b>:<br/> | |
* <b>EOMONTH</b>(<b>start_date</b>,<b>months</b>)<p/> | |
* <p/> | |
* <b>start_date</b> is the starting date of the calculation | |
* <b>months</b> is the number of months to be added to <b>start_date</b>, | |
* to give a new date. For this new date, <b>EOMONTH</b> returns the date of | |
* the last day of the month. <b>months</b> may be positive (in the future), | |
* zero or negative (in the past). | |
*/ | |
public class EOMonth implements FreeRefFunction { | |
public static final FreeRefFunction instance = new EOMonth(); | |
@Override | |
public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { | |
if (args.length != 2) { | |
return ErrorEval.VALUE_INVALID; | |
} | |
try { | |
double startDateAsNumber = NumericFunction.singleOperandEvaluate(args[0], ec.getRowIndex(), ec.getColumnIndex()); | |
int months = (int) NumericFunction.singleOperandEvaluate(args[1], ec.getRowIndex(), ec.getColumnIndex()); | |
// Excel treats date 0 as 1900-01-00; EOMONTH results in 1900-01-31 | |
if (startDateAsNumber >= 0.0 && startDateAsNumber < 1.0) { | |
startDateAsNumber = 1.0; | |
} | |
Date startDate = DateUtil.getJavaDate(startDateAsNumber, false); | |
Calendar cal = LocaleUtil.getLocaleCalendar(); | |
cal.setTime(startDate); | |
cal.clear(Calendar.HOUR); | |
cal.set(Calendar.HOUR_OF_DAY, 0); | |
cal.clear(Calendar.MINUTE); | |
cal.clear(Calendar.SECOND); | |
cal.clear(Calendar.MILLISECOND); | |
cal.add(Calendar.MONTH, months + 1); | |
cal.set(Calendar.DAY_OF_MONTH, 1); | |
cal.add(Calendar.DAY_OF_MONTH, -1); | |
return new NumberEval(DateUtil.getExcelDate(cal.getTime())); | |
} catch (EvaluationException e) { | |
return e.getErrorEval(); | |
} | |
} | |
} |