blob: 184866e7c2ba92517777ffc6a6c319c20f162afa [file] [log] [blame]
/*
* ====================================================================
* 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 org.apache.poi.ss.formula.eval.BlankEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.EvaluationException;
import org.apache.poi.ss.formula.eval.MissingArgEval;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.OperandResolver;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.usermodel.DateUtil;
/**
* Implementation for the Excel function WEEKDAY
*
* @author Thies Wellpott
*/
public final class WeekdayFunc implements Function {
//or: extends Var1or2ArgFunction {
public static final Function instance = new WeekdayFunc();
private WeekdayFunc() {
// no fields to initialise
}
/* for Var1or2ArgFunction:
@Override
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
}
@Override
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
}
*/
/**
* Perform WEEKDAY(date, returnOption) function.
* Note: Parameter texts are from German EXCEL-2010 help.
* Parameters in args[]:
* args[0] serialDate
* EXCEL-date value
* Standardmaessig ist der 1. Januar 1900 die fortlaufende Zahl 1 und
* der 1. Januar 2008 die fortlaufende Zahl 39.448, da dieser Tag nach 39.448 Tagen
* auf den 01.01.1900 folgt.
* @return Option (optional)
* Bestimmt den Rueckgabewert:
1 oder nicht angegeben Zahl 1 (Sonntag) bis 7 (Samstag). Verhaelt sich wie fruehere Microsoft Excel-Versionen.
2 Zahl 1 (Montag) bis 7 (Sonntag).
3 Zahl 0 (Montag) bis 6 (Sonntag).
11 Die Zahlen 1 (Montag) bis 7 (Sonntag)
12 Die Zahlen 1 (Dienstag) bis 7 (Montag)
13 Die Zahlen 1 (Mittwoch) bis 7 (Dienstag)
14 Die Zahlen 1 (Donnerstag) bis 7 (Mittwoch)
15 Die Zahlen 1 (Freitag) bis 7 (Donnerstag)
16 Die Zahlen 1 (Samstag) bis 7 (Freitag)
17 Die Zahlen 1 (Sonntag) bis 7 (Samstag)
*/
public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
try {
if (args.length < 1 || args.length > 2) {
return ErrorEval.VALUE_INVALID;
}
// extract first parameter
ValueEval serialDateVE = OperandResolver.getSingleValue(args[0], srcRowIndex, srcColumnIndex);
double serialDate = OperandResolver.coerceValueToDouble(serialDateVE);
if (!DateUtil.isValidExcelDate(serialDate)) {
return ErrorEval.NUM_ERROR; // EXCEL uses this and no VALUE_ERROR
}
Calendar date = DateUtil.getJavaCalendar(serialDate, false); // (XXX 1904-windowing not respected)
int weekday = date.get(Calendar.DAY_OF_WEEK); // => sunday = 1, monday = 2, ..., saturday = 7
// extract second parameter
int returnOption = 1; // default value
if (args.length == 2) {
ValueEval ve = OperandResolver.getSingleValue(args[1], srcRowIndex, srcColumnIndex);
if (ve == MissingArgEval.instance || ve == BlankEval.instance) {
return ErrorEval.NUM_ERROR; // EXCEL uses this and no VALUE_ERROR
}
returnOption = OperandResolver.coerceValueToInt(ve);
if (returnOption == 2) {
returnOption = 11; // both mean the same
}
} // if
// perform calculation
double result;
if (returnOption == 1) {
result = weekday;
// value 2 is handled above (as value 11)
} else if (returnOption == 3) {
result = (weekday + 6 - 1) % 7;
} else if (returnOption >= 11 && returnOption <= 17) {
// rotate in the value range 1 to 7
result = (weekday + 6 - (returnOption - 10)) % 7 + 1.;
} else {
// EXCEL uses this and no VALUE_ERROR
return ErrorEval.NUM_ERROR;
}
return new NumberEval(result);
} catch (EvaluationException e) {
return e.getErrorEval();
}
} // evaluate()
}