| /* |
| * ==================================================================== |
| * 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) { |
| result = (weekday + 6 - (returnOption - 10)) % 7 + 1; // rotate in the value range 1 to 7 |
| } else { |
| return ErrorEval.NUM_ERROR; // EXCEL uses this and no VALUE_ERROR |
| } |
| |
| return new NumberEval(result); |
| } catch (EvaluationException e) { |
| return e.getErrorEval(); |
| } |
| } // evaluate() |
| |
| } |