001    /**
002     * Copyright 2004-2013 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.hr.time.util;
017    
018    import java.math.BigDecimal;
019    import java.net.UnknownHostException;
020    import java.sql.Date;
021    import java.sql.Timestamp;
022    import java.text.ParseException;
023    import java.text.SimpleDateFormat;
024    import java.util.ArrayList;
025    import java.util.Calendar;
026    import java.util.GregorianCalendar;
027    import java.util.LinkedHashMap;
028    import java.util.List;
029    import java.util.Map;
030    import java.util.TimeZone;
031    
032    import javax.servlet.http.HttpServletRequest;
033    
034    import org.apache.commons.lang.ObjectUtils;
035    import org.apache.commons.lang.StringUtils;
036    import org.apache.log4j.Logger;
037    import org.joda.time.DateTime;
038    import org.joda.time.DateTimeZone;
039    import org.joda.time.Days;
040    import org.joda.time.Interval;
041    import org.joda.time.Period;
042    import org.kuali.hr.time.assignment.Assignment;
043    import org.kuali.hr.time.calendar.CalendarEntries;
044    import org.kuali.hr.time.service.base.TkServiceLocator;
045    import org.kuali.hr.time.task.Task;
046    import org.kuali.rice.core.api.config.property.ConfigContext;
047    import org.kuali.rice.core.api.util.RiceKeyConstants;
048    import org.kuali.rice.krad.util.GlobalVariables;
049    import org.kuali.rice.krad.util.KRADConstants;
050    
051    public class TKUtils {
052    
053        private static final Logger LOG = Logger.getLogger(TKUtils.class);
054    
055        public static java.sql.Date getCurrentDate() {
056            return getTimelessDate(null);
057        }
058    
059        /**
060         * @param dateString the format has to be mm/dd/yyyy
061         * @return dayOfMonth
062         */
063        public static String getDayOfMonthFromDateString(String dateString) {
064            String[] date = dateString.split("/");
065            return date[1];
066        }
067    
068        public static String getSystemTimeZone() {
069            String configTimezone = TimeZone.getDefault().getID();
070            if (ConfigContext.getCurrentContextConfig() != null
071                    && StringUtils.isNotBlank(ConfigContext.getCurrentContextConfig().getProperty(TkConstants.ConfigSettings.KPME_SYSTEM_TIMEZONE).trim())) {
072                String tempTimeZoneId = ConfigContext.getCurrentContextConfig().getProperty(TkConstants.ConfigSettings.KPME_SYSTEM_TIMEZONE);
073    
074                if (TimeZone.getTimeZone(tempTimeZoneId) != null) {
075                    configTimezone = ConfigContext.getCurrentContextConfig().getProperty(TkConstants.ConfigSettings.KPME_SYSTEM_TIMEZONE);
076                } else {
077                    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.");
078                }
079            }
080    
081    
082            return configTimezone;
083        }
084    
085        public static DateTimeZone getSystemDateTimeZone() {
086            return DateTimeZone.forID(TKUtils.getSystemTimeZone());
087        }
088    
089        public static final Date END_OF_TIME = Date.valueOf("9999-12-31");
090    
091        /**
092         * Returns a enforced timeless version of the provided date, if the date is
093         * null the current date is returned.
094         *
095         * @param date
096         * @return A java.sql.Date version of the provided date, if provided date is
097         *         null, the current date is returned.
098         */
099        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    }