View Javadoc

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