ucAdjustWorkdays
Purpose
This is used to allow special date arithmetic. A true value is returned if a change has been made.
Applies To
Add Issue screen
Signature
public boolean ucAdjustWorkdays (int action, DateCalculator dc)
Notes
Example
// Setup global vars used by ucAdjustWorkdays Calendar [] holidays = null; static final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000; // Setup methods used by ucAdjustWorkdays int myCompare (Calendar c1, Calendar c2) { // Note: This looks like it's trying to get the same day // by dividing by MILLIS_PER_DAY, // but that can cross date boundaries; // probably due to the TZ offset, don't want to change this // at the moment as it seeems to wrork for what is needed. long t1 = c1.getTimeInMillis() / MILLIS_PER_DAY; long t2 = c2.getTimeInMillis() / MILLIS_PER_DAY; if (t1 > t2) { return 1; } else if (t1 < t2) { return -1; } return 0; } void backupOneBusinessDay (Calendar st, Calendar start) { st.add(Calendar.DATE, -1); start.add(Calendar.DATE, -1); if (st.get(Calendar.DAY_OF_WEEK) > 6) { // saturday st.add(Calendar.DATE, -1); start.add(Calendar.DATE, -1); } if (st.get(Calendar.DAY_OF_WEEK) == 1) { // sunday st.add(Calendar.DATE, -2); start.add(Calendar.DATE, -2); } } void advanceOneBusinessDay (Calendar st, Calendar start) { st.add(Calendar.DATE, 1); start.add(Calendar.DATE, 1); if (st.get(Calendar.DAY_OF_WEEK) == 7) { // saturday st.add(Calendar.DATE, 2); start.add(Calendar.DATE, 2); } if (st.get(Calendar.DAY_OF_WEEK) == 1) { // sunday st.add(Calendar.DATE, 1); start.add(Calendar.DATE, 1); } } public void setHolidays (Connection con, SesameSession session) throws Exception { holidays = new Calendar[9]; DbTime t = new DbTime(session, con); Calendar c = t.getUserNow() ; int i = 0; c.set(Calendar.AM_PM, Calendar.PM); // New Year’s Day Friday, January 1, 2010 c.set(2010, 0, 1, 0, 0, 0); c.set(Calendar.MILLISECOND, 0); c.add(Calendar.DATE, 1); c.add(Calendar.DATE, -1); holidays[i++] = (Calendar) c.clone(); // President’s Day Monday, February 15, 2010 c.set(2010, 1, 15); c.add(Calendar.DATE, 1); c.add(Calendar.DATE, -1); holidays[i++] = (Calendar) c.clone(); // Memorial Day Monday, May 31, 2010 c.set(2010, 4, 31); c.add(Calendar.DATE, 1); c.add(Calendar.DATE, -1); holidays[i++] = (Calendar) c.clone(); // Independence Day Monday, July 5, 2010 c.set(2010, 6, 5); c.add(Calendar.DATE, 1); c.add(Calendar.DATE, -1); holidays[i++] = (Calendar) c.clone(); // Labor Day Monday, September 6, 2010 c.set(2008, 8, 6); c.add(Calendar.DATE, 1); c.add(Calendar.DATE, -1); holidays[i++] = (Calendar) c.clone(); // Thanksgiving Day Thursday, November 25, 2010 c.set(2010,10, 25); c.add(Calendar.DATE, 1); c.add(Calendar.DATE, -1); holidays[i++] = (Calendar) c.clone(); // Day after Thanksgiving Friday, November 26, 2010 c.set(2010,10, 26); c.add(Calendar.DATE, 1); c.add(Calendar.DATE, -1); holidays[i++] = (Calendar) c.clone(); // Christmas Eve Friday, December 24, 2010 c.set(2010,11, 24); c.add(Calendar.DATE, 1); c.add(Calendar.DATE, -1); holidays[i++] = (Calendar) c.clone(); // Christmas Day Monday, December 27, 2010 c.set(2010,11, 27); c.add(Calendar.DATE, 1); c.add(Calendar.DATE, -1); holidays[i++] = (Calendar) c.clone(); // for (i=0; i < holidays.length; i++) w("holiday[" + i + "]: " + dmpD(holidays[i])); } public boolean ucAdjustWorkdays (int action, DateCalculator dc) throws Exception { boolean changed = false; if (holidays == null) { SesameSession session = SesameSession.getSession(); Connection con = null; try { con = Z.pool.getConnection("ucAdjustWorkdays"); setHolidays (con, session); } catch (Exception e) { holidays = null; Z.log.writeToLog(Z.log.ERROR, "UC: ucAdjustWorkdays Exception: " + e); ErrorWriter.write(e, ErrorWriter.LOGERR); } finally { if (con != null) { Z.pool.close(con); } } } Calendar start = dc.getStartDate(); Calendar end = dc.getEndDate(); double interval = dc.getInterval(); boolean isReversed = false; // w("action ==? : " + (action == DateCalculator.SET_INTERVAL)); // if we're setting the interval, check for holidays inside... if (action == DateCalculator.SET_INTERVAL) { if (start.before(end)) { Calendar t = start; start = end; end = t; interval = - interval; isReversed = true; } for (int i=0; i < holidays.length; i++) { // w("holiday: " + dmpD(holidays[i]) + "; start: " + dmpD(start) + // "; end: " + dmpD(end) + "; mycomp: " + myCompare(start, holidays[i]) + // "; comp2: " + myCompare(end, holidays[i])); if (!start.before(holidays[i]) && !end.after(holidays[i])) { interval -= 1.d; } } if (isReversed) { interval = - interval; } if (dc.getInterval() != interval) { dc.setInterval(interval); return true; } return false; } // if (dc.getInterval() == 0.d) { return false; } // w("start: " + dmpD(start) +"; end: " + dmpD(end) + "; interval: " + interval); // workaound for rules bug passing in interval with wrong sign in 6.0.1 code. // this can be removed in 6.1. if (start.after(end) && interval > 0.d || start.before(end) && interval < 0.d ) { interval = -interval; } Calendar st = (Calendar) start.clone(); st.set(Calendar.AM_PM, Calendar.PM); st.set(Calendar.HOUR, 0); st.set(Calendar.MINUTE, 0); st.set(Calendar.SECOND, 0); st.set(Calendar.MILLISECOND, 0); st.add(Calendar.DATE, 1); st.add(Calendar.DATE, -1); Calendar en = (Calendar) end.clone(); en.set(Calendar.AM_PM, Calendar.PM); en.set(Calendar.HOUR, 0); en.set(Calendar.MINUTE, 0); en.set(Calendar.SECOND, 0); en.set(Calendar.MILLISECOND, 0); en.add(Calendar.DATE, 1); en.add(Calendar.DATE, -1); // if these are reversed, then swap the dates // for comparison, so the first date is always // before the second. when we adjust below, // we take this into account. boolean reversed = en.before(st); if (reversed) { Calendar h = st; st = en; en = h; } int s = -1; int e = -1; for (int i=0; i
= 0 ) { s = i; break; } } // if all holidays are before start date, nothing to do. if (s == -1) { return false; } for (int i= holidays.length; i-- > 0;) { if (myCompare (holidays[i], en) <= 0) { e = i; break; } } if (e < s) { return false; } // no holidays in between // number of holidays is the number in between int num = e - s + 1; // step through adding the days one at a time so we // can skip over additional holidays or weekends // as we go. note that we are adjusting the date in the date calculator // which is actually a reference (pointer) to the original // object, so we are always adjusting the end date for (int i=0; i
0 && myCompare (st, holidays[s-1]) == 0 ) { s--; num++; } } else { advanceOneBusinessDay(en, end); // if new day is a holiday, skip another one. if (e < holidays.length && myCompare(en, holidays[e+1]) == 0 ) { num++; e++; } } } return changed; }