View Javadoc

1   /**
2    * Copyright 2004-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.hr.time.util;
17  
18  import java.math.BigDecimal;
19  import java.net.UnknownHostException;
20  import java.sql.Date;
21  import java.sql.Timestamp;
22  import java.text.ParseException;
23  import java.text.SimpleDateFormat;
24  import java.util.ArrayList;
25  import java.util.Calendar;
26  import java.util.GregorianCalendar;
27  import java.util.LinkedHashMap;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.TimeZone;
31  
32  import javax.servlet.http.HttpServletRequest;
33  
34  import org.apache.commons.lang.ObjectUtils;
35  import org.apache.commons.lang.StringUtils;
36  import org.apache.log4j.Logger;
37  import org.joda.time.DateTime;
38  import org.joda.time.DateTimeZone;
39  import org.joda.time.Days;
40  import org.joda.time.Interval;
41  import org.joda.time.Period;
42  import org.kuali.hr.time.assignment.Assignment;
43  import org.kuali.hr.time.calendar.CalendarEntries;
44  import org.kuali.hr.time.service.base.TkServiceLocator;
45  import org.kuali.hr.time.task.Task;
46  import org.kuali.rice.core.api.config.property.ConfigContext;
47  import org.kuali.rice.core.api.util.RiceKeyConstants;
48  import org.kuali.rice.krad.util.GlobalVariables;
49  import org.kuali.rice.krad.util.KRADConstants;
50  
51  public class TKUtils {
52  
53      private static final Logger LOG = Logger.getLogger(TKUtils.class);
54  
55      public static java.sql.Date getCurrentDate() {
56          return getTimelessDate(null);
57      }
58  
59      /**
60       * @param dateString the format has to be mm/dd/yyyy
61       * @return dayOfMonth
62       */
63      public static String getDayOfMonthFromDateString(String dateString) {
64          String[] date = dateString.split("/");
65          return date[1];
66      }
67  
68      public static String getSystemTimeZone() {
69          String configTimezone = TimeZone.getDefault().getID();
70          if (ConfigContext.getCurrentContextConfig() != null
71                  && StringUtils.isNotBlank(ConfigContext.getCurrentContextConfig().getProperty(TkConstants.ConfigSettings.KPME_SYSTEM_TIMEZONE).trim())) {
72              String tempTimeZoneId = ConfigContext.getCurrentContextConfig().getProperty(TkConstants.ConfigSettings.KPME_SYSTEM_TIMEZONE);
73  
74              if (TimeZone.getTimeZone(tempTimeZoneId) != null) {
75                  configTimezone = ConfigContext.getCurrentContextConfig().getProperty(TkConstants.ConfigSettings.KPME_SYSTEM_TIMEZONE);
76              } else {
77                  LOG.error("Timezone set by configuration parameter " + TkConstants.ConfigSettings.KPME_SYSTEM_TIMEZONE + " is not a valid time zone id.  Using the systems default time zone instead.");
78              }
79          }
80  
81  
82          return configTimezone;
83      }
84  
85      public static DateTimeZone getSystemDateTimeZone() {
86          return DateTimeZone.forID(TKUtils.getSystemTimeZone());
87      }
88  
89      public static final Date END_OF_TIME = Date.valueOf("9999-12-31");
90  
91      /**
92       * Returns a enforced timeless version of the provided date, if the date is
93       * null the current date is returned.
94       *
95       * @param date
96       * @return A java.sql.Date version of the provided date, if provided date is
97       *         null, the current date is returned.
98       */
99      public static java.sql.Date getTimelessDate(java.util.Date date) {
100         java.sql.Date jsd = null;
101         if (date == null) {
102             jsd = new java.sql.Date(System.currentTimeMillis());
103         } else {
104             jsd = new java.sql.Date(date.getTime());
105         }
106         return jsd;
107     }
108 
109     public static long getDaysBetween(Calendar startDate, Calendar endDate) {
110         Calendar date = (Calendar) startDate.clone();
111         long daysBetween = 0;
112         while (date.before(endDate)) {
113             date.add(Calendar.DAY_OF_MONTH, 1);
114             daysBetween++;
115         }
116         return daysBetween;
117     }
118 
119     public static long getDaysBetween(java.util.Date startDate, java.util.Date endDate) {
120         Calendar beginCal = GregorianCalendar.getInstance();
121         Calendar endCal = GregorianCalendar.getInstance();
122         beginCal.setTime(startDate);
123         endCal.setTime(endDate);
124 
125         return getDaysBetween(beginCal, endCal);
126     }
127 
128     public static BigDecimal getHoursBetween(long start, long end) {
129         long diff = end - start;
130         BigDecimal hrsReminder = new BigDecimal((diff / 3600000.0) % 24);
131         // if the hours is exact duplicate of 24 hours
132         if (hrsReminder.compareTo(BigDecimal.ZERO) == 0 && diff > 0) {
133             return new BigDecimal(diff / 3600000.0).setScale(TkConstants.BIG_DECIMAL_SCALE, TkConstants.BIG_DECIMAL_SCALE_ROUNDING).abs();
134         }
135         return hrsReminder.setScale(TkConstants.BIG_DECIMAL_SCALE, TkConstants.BIG_DECIMAL_SCALE_ROUNDING).abs();
136     }
137 
138 
139 
140     public static int getNumberOfWeeks(java.util.Date beginDate, java.util.Date endDate) {
141 
142         DateTime beginTime = new DateTime(beginDate);
143         DateTime endTime = new DateTime(endDate);
144 
145         int numOfDays = Days.daysBetween(beginTime, endTime).getDays();
146         int numOfWeeks = numOfDays / 7;
147         if (numOfDays % 7 != 0) {
148             numOfWeeks++;
149         }
150         return numOfWeeks;
151     }
152 
153     public static String formatAssignmentKey(Long jobNumber, Long workArea, Long task) {
154     	String jobNumberString = ObjectUtils.toString(jobNumber, "0");
155     	String workAreaString = ObjectUtils.toString(workArea, "0");
156     	String taskString = ObjectUtils.toString(task, "0");
157         return jobNumberString + TkConstants.ASSIGNMENT_KEY_DELIMITER + workAreaString + TkConstants.ASSIGNMENT_KEY_DELIMITER + taskString;
158     }
159 
160     public static Map<String, String> formatAssignmentDescription(Assignment assignment) {
161         Map<String, String> assignmentDescriptions = new LinkedHashMap<String, String>();
162         String assignmentDescKey = formatAssignmentKey(assignment.getJobNumber(), assignment.getWorkArea(), assignment.getTask());
163         String assignmentDescValue = getAssignmentString(assignment);
164         assignmentDescriptions.put(assignmentDescKey, assignmentDescValue);
165 
166         return assignmentDescriptions;
167     }
168 
169     public static String getAssignmentString(Assignment assignment) {
170 
171 
172         if (assignment.getWorkAreaObj() == null
173                 || assignment.getJob() == null
174                 || assignment.getJobNumber() == null) {
175             return "";     // getAssignment() of AssignmentService can return an empty assignment
176         }
177         
178        String stringTemp = assignment.getWorkAreaObj().getDescription() + " : $" 
179        				+ assignment.getJob().getCompRate().setScale(TkConstants.BIG_DECIMAL_SCALE) 
180        				+ " Rcd " + assignment.getJobNumber() + " " + assignment.getJob().getDept();
181        if(assignment.getTask()!= null) {
182 	       	Task aTask = TkServiceLocator.getTaskService().getTask(assignment.getTask(), assignment.getEffectiveDate());
183 	       	if(aTask != null) {
184 	       		// do not display task description if the task is the default one
185 	        	// default task is created in getTask() of TaskService
186 	        	if(!aTask.getDescription().equals(TkConstants.TASK_DEFAULT_DESP)) {
187 	        		stringTemp += " " +  aTask.getDescription();
188 	        	}
189 	       	} 
190        }
191        return stringTemp;
192     }
193 
194     /**
195      * Constructs a list of Day Spans for the pay calendar entry provided. You
196      * must also provide a DateTimeZone so that we can create relative boundaries.
197      *
198      * @param calendarEntry
199      * @param timeZone
200      * @return
201      */
202     public static List<Interval> getDaySpanForCalendarEntry(CalendarEntries calendarEntry, DateTimeZone timeZone) {
203         DateTime beginDateTime = calendarEntry.getBeginLocalDateTime().toDateTime(timeZone);
204         DateTime endDateTime = calendarEntry.getEndLocalDateTime().toDateTime(timeZone);
205 
206         List<Interval> dayIntervals = new ArrayList<Interval>();
207 
208         DateTime currDateTime = beginDateTime;
209         while (currDateTime.isBefore(endDateTime)) {
210             DateTime prevDateTime = currDateTime;
211             currDateTime = currDateTime.plusDays(1);
212             Interval daySpan = new Interval(prevDateTime, currDateTime);
213             dayIntervals.add(daySpan);
214         }
215 
216         return dayIntervals;
217     }
218     
219 
220     /**
221      * Includes partial weeks if the time range provided does not divide evenly
222      * into 7 day spans.
223      *
224      * @param beginDate Starting Date/Time
225      * @param endDate   Ending Date/Time
226      * @return A List of Intervals of 7 day spans. The last Interval in the list
227      *         may be less than seven days.
228      */
229     public static List<Interval> getWeekIntervals(java.util.Date beginDate, java.util.Date endDate) {
230         List<Interval> intervals = new ArrayList<Interval>();
231         DateTime beginTime = new DateTime(beginDate);
232         DateTime endTime = new DateTime(endDate);
233 
234         int dayIncrement = 7;
235         DateTime previous = beginTime;
236         DateTime nextTime = previous.plusDays(dayIncrement);
237         while (nextTime.isBefore(endTime)) {
238             Interval interval = new Interval(previous, nextTime);
239             intervals.add(interval);
240             previous = nextTime;
241             nextTime = previous.plusDays(dayIncrement);
242         }
243 
244         if (previous.isBefore(endTime)) {
245             // add a partial week.
246             Interval interval = new Interval(previous, endTime);
247             intervals.add(interval);
248         }
249 
250         return intervals;
251     }
252 
253     public static long convertHoursToMillis(BigDecimal hours) {
254         return hours.multiply(TkConstants.BIG_DECIMAL_MS_IN_H, TkConstants.MATH_CONTEXT).longValue();
255     }
256 
257     public static BigDecimal convertMillisToHours(long millis) {
258         return (new BigDecimal(millis)).divide(TkConstants.BIG_DECIMAL_MS_IN_H, TkConstants.MATH_CONTEXT);
259     }
260 
261     public static BigDecimal convertMillisToMinutes(long millis) {
262         return (new BigDecimal(millis)).divide(TkConstants.BIG_DECIMAL_MS_IN_M, TkConstants.MATH_CONTEXT);
263     }
264     
265     public static BigDecimal convertMillisToDays(long millis) {
266         BigDecimal hrs = convertMillisToHours(millis);
267         return hrs.divide(TkConstants.BIG_DECIMAL_HRS_IN_DAY, TkConstants.MATH_CONTEXT);
268     }
269 
270     public static BigDecimal convertMinutesToHours(BigDecimal minutes) {
271         return minutes.divide(TkConstants.BIG_DECIMAL_60, TkConstants.MATH_CONTEXT);
272     }
273 
274     public static int convertMillisToWholeDays(long millis) {
275         BigDecimal days = convertMillisToDays(millis);
276         return Integer.parseInt(days.setScale(0, BigDecimal.ROUND_UP).toString());
277     }
278 
279     /*
280       * Compares and confirms if the start of the day is at midnight or on a virtual day boundary
281       * returns true if at midnight false otherwise(assuming 24 hr days)
282       */
283     public static boolean isVirtualWorkDay(Calendar payCalendarStartTime) {
284         return (payCalendarStartTime.get(Calendar.HOUR_OF_DAY) != 0 || payCalendarStartTime.get(Calendar.MINUTE) != 0
285                 && payCalendarStartTime.get(Calendar.AM_PM) != Calendar.AM);
286     }
287 
288     /**
289      * Creates a Timestamp object using Jodatime as an intermediate data structure
290      * from the provided date and time string. (From the form POST and javascript
291      * formats)
292      *
293      * @param dateStr (the format is 01/01/2011)
294      * @param timeStr (the format is 8:0)
295      * @return Timestamp
296      */
297     public static Timestamp convertDateStringToTimestamp(String dateStr, String timeStr) {
298         // the date/time format is defined in tk.calendar.js. For now, the format is 11/17/2010 8:0
299         String[] date = dateStr.split("/");
300         String[] time = timeStr.split(":");
301 
302         DateTimeZone dtz = DateTimeZone.forID(TkServiceLocator.getTimezoneService().getUserTimezone());
303 
304         // this is from the jodattime javadoc:
305         // DateTime(int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minuteOfHour, int secondOfMinute, int millisOfSecond, DateTimeZone zone)
306         // Noted that the month value is the actual month which is different than the java date object where the month value is the current month minus 1.
307         // I tried to use the actual month in the code as much as I can to reduce the convertions.
308         DateTime dateTime = new DateTime(
309                 Integer.parseInt(date[2]),
310                 Integer.parseInt(date[0]),
311                 Integer.parseInt(date[1]),
312                 Integer.parseInt(time[0]),
313                 Integer.parseInt(time[1]),
314                 0, 0, dtz);
315 
316         return new Timestamp(dateTime.getMillis());
317     }
318     
319     public static Timestamp convertDateStringToTimestampWithoutZone(String dateStr, String timeStr) {
320         // the date/time format is defined in tk.calendar.js. For now, the format is 11/17/2010 8:0
321         String[] date = dateStr.split("/");
322         String[] time = timeStr.split(":");
323 
324         // this is from the jodattime javadoc:
325         // DateTime(int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minuteOfHour, int secondOfMinute, int millisOfSecond, DateTimeZone zone)
326         // Noted that the month value is the actual month which is different than the java date object where the month value is the current month minus 1.
327         // I tried to use the actual month in the code as much as I can to reduce the convertions.
328         DateTime dateTime = new DateTime(
329                 Integer.parseInt(date[2]),
330                 Integer.parseInt(date[0]),
331                 Integer.parseInt(date[1]),
332                 Integer.parseInt(time[0]),
333                 Integer.parseInt(time[1]),
334                 0, 0);
335 
336         return new Timestamp(dateTime.getMillis());
337     }
338     
339    public static String getIPAddressFromRequest(HttpServletRequest request) {
340         // Check for IPv6 addresses - Not sure what to do with them at this point.
341         // TODO: IPv6 - I see these on my local machine.
342         String ip = request.getRemoteAddr();
343         if (ip.indexOf(':') > -1) {
344             LOG.warn("ignoring IPv6 address for clock-in: " + ip);
345             ip = "";
346         }
347 
348         return ip;
349     }
350 
351     public static Date createDate(int month, int day, int year, int hours, int minutes, int seconds) {
352         DateTime dt = new DateTime(year, month, day, hours, minutes, seconds, 0);
353         return new Date(dt.getMillis());
354     }
355 
356     public static String getIPNumber() {
357         try {
358             return java.net.InetAddress.getLocalHost().getHostAddress();
359         } catch (UnknownHostException e) {
360             return "unknown";
361         }
362     }
363     //Used to preserve active row fetching based on max(timestamp)
364     public static Timestamp subtractOneSecondFromTimestamp(Timestamp originalTimestamp) {
365         DateTime dt = new DateTime(originalTimestamp);
366         dt = dt.minusSeconds(1);
367         return new Timestamp(dt.getMillis());
368     }
369 
370     public static Date subtractOneMillisecondFromDate(java.util.Date date) {
371         DateTime dt = new DateTime(date);
372         dt = dt.minusMillis(1);
373         return new Date(dt.getMillis());
374     }
375 
376     public static String formatDate(Date dt) {
377         SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
378         return sdf.format(dt);
379     }
380 
381     
382     public static String formatDateTime(Timestamp timestamp){
383     	Date dt = new Date(timestamp.getTime());
384     	SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
385         return sdf.format(dt);
386     }
387     
388     public static Date formatDateString(String date){
389     	SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
390     	try {
391 			return new Date(sdf.parse(date).getTime());
392 		} catch (ParseException e) {
393 			return null;
394 		}
395     }
396     
397     /**
398      * Method to obtain the timezone offset string for the specified date time.
399      *
400      * Examples:
401      *
402      * -0500
403      * -0800
404      *
405      * @param date
406      * @return
407      */
408     public static String getTimezoneOffset(DateTime date) {
409         StringBuilder o = new StringBuilder();
410 
411         int offsetms = date.getZone().getOffset(date);
412         boolean negative = offsetms < 0;
413         if (negative) offsetms = offsetms * -1;
414 
415         Period period = new Period(offsetms);
416         if (negative) o.append('-');
417         o.append(StringUtils.leftPad(period.getHours() + "", 2, '0'));
418         o.append(StringUtils.leftPad(period.getMinutes() + "", 2, '0'));
419 
420         return o.toString();
421     }
422 
423     public static String arrayToString(String[] stringArray) {
424         StringBuilder str = new StringBuilder();
425         for (String string : stringArray) {
426             str.append(string);
427         }
428         return str.toString();
429     }
430 
431     /**
432      * Get the session timeout time. If it's not defined in the (local) config file, give it a default time.
433      */
434     public static int getSessionTimeoutTime() {
435         return StringUtils.isBlank(ConfigContext.getCurrentContextConfig().getProperty(TkConstants.ConfigSettings.SESSION_TIMEOUT))
436                 ? 2700 :
437                 Integer.parseInt(ConfigContext.getCurrentContextConfig().getProperty(TkConstants.ConfigSettings.SESSION_TIMEOUT));
438     }
439     
440     /**
441      * Creates a Timestamp object using Jodatime as an intermediate data structure
442      * from the provided date and time string. (From the form POST and javascript
443      * formats)
444      *
445      * @param dateStr (the format is 01/01/2011)
446      * @return Timestamp
447      */
448     public static Timestamp convertDateStringToTimestamp(String dateStr) {
449         // the date/time format is defined in tk.calendar.js. the format is 11/17/2010
450         String[] date = dateStr.split("/");
451 
452         DateTimeZone dtz = DateTimeZone.forID(TkServiceLocator.getTimezoneService().getUserTimezone());
453 
454         // this is from the jodattime javadoc:
455         // DateTime(int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minuteOfHour, int secondOfMinute, int millisOfSecond, DateTimeZone zone)
456         // Noted that the month value is the actual month which is different than the java date object where the month value is the current month minus 1.
457         // I tried to use the actual month in the code as much as I can to reduce the convertions.
458         DateTime dateTime = new DateTime(
459                 Integer.parseInt(date[2]),
460                 Integer.parseInt(date[0]),
461                 Integer.parseInt(date[1]),
462                 0, 0, 0, 0, dtz);
463 
464         return new Timestamp(dateTime.getMillis());
465     }
466 
467     /**
468      * Creates a Timestamp object using Jodatime as an intermediate data structure
469      * from the provided date and time string. (From the form POST and javascript
470      * formats)
471      *
472      * @param dateStr (the format is 01/01/2011)
473      * @return Timestamp
474      */
475     public static Timestamp convertDateStringToTimestampNoTimezone(String dateStr) {
476         // the date/time format is defined in tk.calendar.js. the format is 11/17/2010
477         String[] date = dateStr.split("/");
478 
479         // this is from the jodattime javadoc:
480         // DateTime(int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minuteOfHour, int secondOfMinute, int millisOfSecond, DateTimeZone zone)
481         // Noted that the month value is the actual month which is different than the java date object where the month value is the current month minus 1.
482         // I tried to use the actual month in the code as much as I can to reduce the convertions.
483         DateTime dateTime = new DateTime(
484                 Integer.parseInt(date[2]),
485                 Integer.parseInt(date[0]),
486                 Integer.parseInt(date[1]),
487                 0, 0, 0, 0);
488 
489         return new Timestamp(dateTime.getMillis());
490     }
491 
492     
493     public static Timestamp getCurrentTimestamp() {
494         return new Timestamp(System.currentTimeMillis());
495     }
496     
497     public static List<Interval> createDaySpan(DateTime beginDateTime, DateTime endDateTime, DateTimeZone zone) {
498         beginDateTime = beginDateTime.toDateTime(zone);
499         endDateTime = endDateTime.toDateTime(zone);
500         List<Interval> dayIntervals = new ArrayList<Interval>();
501 
502         DateTime currDateTime = beginDateTime;
503         while (currDateTime.isBefore(endDateTime)) {
504             DateTime prevDateTime = currDateTime;
505             currDateTime = currDateTime.plusDays(1);
506             Interval daySpan = new Interval(prevDateTime, currDateTime);
507             dayIntervals.add(daySpan);
508         }
509 
510         return dayIntervals;
511     }
512     
513     public static List<Interval> getDaySpanForCalendarEntry(CalendarEntries calendarEntry) {
514         return getDaySpanForCalendarEntry(calendarEntry, TkServiceLocator.getTimezoneService().getUserTimezoneWithFallback());
515     }
516 
517     public static List<Interval> getFullWeekDaySpanForCalendarEntry(CalendarEntries calendarEntry) {
518         return getFullWeekDaySpanForCalendarEntry(calendarEntry, TkServiceLocator.getTimezoneService().getUserTimezoneWithFallback());
519     }
520     
521     public static List<Interval> getFullWeekDaySpanForCalendarEntry(CalendarEntries calendarEntry, DateTimeZone timeZone) {
522         DateTime beginDateTime = calendarEntry.getBeginLocalDateTime().toDateTime(timeZone);
523         DateTime endDateTime = calendarEntry.getEndLocalDateTime().toDateTime(timeZone);
524 
525         List<Interval> dayIntervals = new ArrayList<Interval>();
526 
527         DateTime currDateTime = beginDateTime;
528         if (beginDateTime.getDayOfWeek() != 7) {
529             currDateTime = beginDateTime.plusDays(0 - beginDateTime.getDayOfWeek());
530         }
531 
532         int afterEndDate = 6 - endDateTime.getDayOfWeek();
533         if (endDateTime.getDayOfWeek() == 7 && endDateTime.getHourOfDay() != 0) {
534             afterEndDate = 6;
535         }
536         if (endDateTime.getHourOfDay() == 0) {
537             afterEndDate += 1;
538         }
539         DateTime aDate = endDateTime.plusDays(afterEndDate);
540         while (currDateTime.isBefore(aDate)) {
541             DateTime prevDateTime = currDateTime;
542             currDateTime = currDateTime.plusDays(1);
543             Interval daySpan = new Interval(prevDateTime, currDateTime);
544             dayIntervals.add(daySpan);
545         }
546 
547         return dayIntervals;
548     }
549     
550     public static java.util.Date removeTime(java.util.Date date) {    
551         Calendar cal = Calendar.getInstance();  
552         cal.setTime(date);  
553         cal.set(Calendar.HOUR_OF_DAY, 0);  
554         cal.set(Calendar.MINUTE, 0);  
555         cal.set(Calendar.SECOND, 0);  
556         cal.set(Calendar.MILLISECOND, 0);  
557         return cal.getTime(); 
558     }
559     
560     public static int getWorkDays(java.util.Date startDate, java.util.Date endDate) {
561     	int dayCounts = 0;
562     	if(startDate.after(endDate)) {
563     		return 0;
564     	}
565     	Calendar cal1 = Calendar.getInstance();
566 		cal1.setTime(startDate);
567 		Calendar cal2 = Calendar.getInstance();
568 		cal2.setTime(endDate);
569 		
570 		while(!cal1.after(cal2)) {
571 			if(cal1.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY 
572 					&& cal1.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY) {
573 				dayCounts ++;		
574 			}
575 			cal1.add(Calendar.DATE, 1);
576 		}
577     	return dayCounts;
578     }
579     
580     public static boolean isWeekend(java.util.Date aDate) {
581     	Calendar cal = Calendar.getInstance();
582 		cal.setTime(aDate);
583     	if(cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY 
584 				|| cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
585 			return true;		
586 		}
587     	return false;
588     }
589     
590     public static java.util.Date addDates(java.util.Date aDate, int aNumber) {
591     	Calendar gc = new GregorianCalendar();
592 		gc.setTime(aDate);
593 		gc.add(Calendar.DAY_OF_YEAR, aNumber);
594 		return gc.getTime();
595     }
596     
597     public static java.util.Date addMonths(java.util.Date aDate, int aNumber) {
598     	Calendar gc = new GregorianCalendar();
599 		gc.setTime(aDate);
600 		gc.add(Calendar.MONTH, aNumber);
601 		if(gc.getActualMaximum(Calendar.DAY_OF_MONTH) < gc.get(Calendar.DATE)) {
602 			gc.set(Calendar.DATE, gc.getActualMaximum(Calendar.DAY_OF_MONTH));
603 		}
604 		
605 		return gc.getTime();
606     }
607     
608     /**
609      * Returns effectiveDate "from" date that's passed in through dateString.
610      * 
611 	 * The "from" dateString can either be from the format "fromDate..toDate" or ">=fromDate", otherwise an empty string is returned.
612 	 * 
613      * @param dateString
614      * @return
615      */
616     public static String getFromDateString(String dateString) {
617     	String toDateString = StringUtils.EMPTY;
618     	
619     	if (StringUtils.startsWith(dateString, ">=")) {
620     		toDateString = StringUtils.substringAfter(dateString, ">=");
621     	} else if (StringUtils.contains(dateString, "..")) {
622     		toDateString = StringUtils.substringBefore(dateString, "..");
623 		}
624     	
625     	return toDateString;
626     }
627     
628     /**
629      * Returns effectiveDate "to" date that's passed in through dateString.
630      * 
631      * The "to" dateString can either be from the format "fromDate..toDate" or "<=toDate", otherwise an empty string is returned.
632      *
633      * @param dateString
634      * @return
635      */
636     public static String getToDateString(String dateString) {
637     	String toDateString = StringUtils.EMPTY;
638     	
639     	if (StringUtils.startsWith(dateString, "<=")) {
640     		toDateString = StringUtils.substringAfter(dateString, "<=");
641     	} else if (StringUtils.contains(dateString, "..")) {
642     		toDateString = StringUtils.substringAfter(dateString, "..");
643 		}
644     	
645     	return toDateString;
646     }
647 
648 
649     /*
650      * Cleans a numerical input so that it can be successfully used with lookups
651      */
652     public static BigDecimal cleanNumeric( String value ) {
653         String cleanedValue = value.replaceAll( "[^-0-9.]", "" );
654         // ensure only one "minus" at the beginning, if any
655         if ( cleanedValue.lastIndexOf( '-' ) > 0 ) {
656             if ( cleanedValue.charAt( 0 ) == '-' ) {
657                 cleanedValue = "-" + cleanedValue.replaceAll( "-", "" );
658             } else {
659                 cleanedValue = cleanedValue.replaceAll( "-", "" );
660             }
661         }
662         // ensure only one decimal in the string
663         int decimalLoc = cleanedValue.lastIndexOf( '.' );
664         if ( cleanedValue.indexOf( '.' ) != decimalLoc ) {
665             cleanedValue = cleanedValue.substring( 0, decimalLoc ).replaceAll( "\\.", "" ) + cleanedValue.substring( decimalLoc );
666         }
667         try {
668             return new BigDecimal( cleanedValue );
669         } catch ( NumberFormatException ex ) {
670             GlobalVariables.getMessageMap().putError(KRADConstants.DOCUMENT_ERRORS, RiceKeyConstants.ERROR_CUSTOM, new String[] { "Invalid Numeric Input: " + value });
671             return null;
672         }
673     }
674 }