001 /**
002 * =========================================
003 * LibFormula : a free Java formula library
004 * =========================================
005 *
006 * Project Info: http://reporting.pentaho.org/libformula/
007 *
008 * (C) Copyright 2006-2007, by Pentaho Corporation and Contributors.
009 *
010 * This library is free software; you can redistribute it and/or modify it under the terms
011 * of the GNU Lesser General Public License as published by the Free Software Foundation;
012 * either version 2.1 of the License, or (at your option) any later version.
013 *
014 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016 * See the GNU Lesser General Public License for more details.
017 *
018 * You should have received a copy of the GNU Lesser General Public License along with this
019 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020 * Boston, MA 02111-1307, USA.
021 *
022 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023 * in the United States and other countries.]
024 *
025 *
026 * ------------
027 * $Id: WeekDayFunction.java 3521 2007-10-16 10:55:14Z tmorgner $
028 * ------------
029 * (C) Copyright 2006-2007, by Pentaho Corporation.
030 */
031 package org.jfree.formula.function.datetime;
032
033 import java.util.Calendar;
034 import java.util.Date;
035
036 import org.jfree.formula.EvaluationException;
037 import org.jfree.formula.FormulaContext;
038 import org.jfree.formula.LibFormulaErrorValue;
039 import org.jfree.formula.function.Function;
040 import org.jfree.formula.function.ParameterCallback;
041 import org.jfree.formula.lvalues.TypeValuePair;
042 import org.jfree.formula.typing.TypeRegistry;
043 import org.jfree.formula.typing.coretypes.NumberType;
044 import org.jfree.formula.util.DateUtil;
045
046 /**
047 * This function extracts the day of week from a date. <p/> The returned value
048 * depends of the Type passed as second argument using the following table:<br/>
049 * <TABLE>
050 * <TR>
051 * <TH>Day of Week</TH>
052 * <TH>Type=1 Result</TH>
053 * <TH>Type=2 Result</TH>
054 * <TH>Type=3 Result</TH>
055 * </TR>
056 * <TR>
057 * <TD>Sunday</TD>
058 * <TD> 1</TD>
059 * <TD> 7</TD>
060 * <TD> 6</TD>
061 * </TR>
062 * <TR>
063 * <TD>Monday</TD>
064 * <TD> 2</TD>
065 * <TD> 1</TD>
066 * <TD> 0</TD>
067 * </TR>
068 * <TR>
069 * <TD>Tuesday</TD>
070 * <TD> 3</TD>
071 * <TD> 2</TD>
072 * <TD> 1</TD>
073 * </TR>
074 * <TR>
075 * <TD>Wednesday</TD>
076 * <TD> 4</TD>
077 * <TD> 3</TD>
078 * <TD> 2</TD>
079 * </TR>
080 * <TR>
081 * <TD>Thursday</TD>
082 * <TD> 5</TD>
083 * <TD> 4</TD>
084 * <TD> 3</TD>
085 * </TR>
086 * <TR>
087 * <TD>Friday</TD>
088 * <TD> 6</TD>
089 * <TD> 5</TD>
090 * <TD> 4</TD>
091 * </TR>
092 * <TR>
093 * <TD>Saturday</TD>
094 * <TD> 7</TD>
095 * <TD> 6</TD>
096 * <TD> 5</TD>
097 * </TR>
098 * </TABLE>
099 *
100 * @author Cedric Pronzato
101 */
102 public class WeekDayFunction implements Function
103 {
104 public WeekDayFunction()
105 {
106 }
107
108 public String getCanonicalName()
109 {
110 return "WEEKDAY";
111 }
112
113 public TypeValuePair evaluate(final FormulaContext context,
114 final ParameterCallback parameters) throws EvaluationException
115 {
116 if (parameters.getParameterCount() > 2)
117 {
118 throw new EvaluationException(LibFormulaErrorValue.ERROR_ARGUMENTS_VALUE);
119 }
120
121 final TypeRegistry typeRegistry = context.getTypeRegistry();
122
123 final Date d = typeRegistry.convertToDate(parameters.getType(0), parameters
124 .getValue(0));
125 int type = 1; // default is Type 1
126 if (parameters.getParameterCount() == 2)
127 {
128 final Number n = typeRegistry.convertToNumber(parameters.getType(1),
129 parameters.getValue(1));
130 if (n == null)
131 {
132 throw new EvaluationException(
133 LibFormulaErrorValue.ERROR_INVALID_ARGUMENT_VALUE);
134 }
135 type = n.intValue();
136 if (type < 1 || type > 3)
137 {
138 throw new EvaluationException(
139 LibFormulaErrorValue.ERROR_INVALID_ARGUMENT_VALUE);
140 }
141 }
142
143 if (d == null)
144 {
145 throw new EvaluationException(
146 LibFormulaErrorValue.ERROR_INVALID_ARGUMENT_VALUE);
147 }
148
149 final Calendar gc = DateUtil.createCalendar(d, context
150 .getLocalizationContext());
151
152 final int dayOfWeek = gc.get(Calendar.DAY_OF_WEEK);
153 // in java Sunday = 1 (= Type 1 of openformula)
154 return new TypeValuePair(NumberType.GENERIC_NUMBER, new Integer(
155 convertType(dayOfWeek, type)));
156 }
157
158 public int convertType(final int currentDayOfWeek, final int type)
159 {
160 if (type == 1)
161 {
162 return currentDayOfWeek;
163 }
164 else if (type == 2)
165 {
166 final int i = ((currentDayOfWeek + 6) % 8);
167 if(i == 7)
168 {
169 return i;
170 }
171 else
172 {
173 return i + 1;
174 }
175 }
176 else
177 {
178 return (currentDayOfWeek + 5) % 7;
179 }
180 }
181 }