Counting only weekend days between two timestamps I am fairly new to the Groovy arena. I recently modified some code to add the following block. This code is added to remove dates we were supposed to remove from the total counts.  This data goes on reports that a bug was noticed, that we weren't removing the queue entry dates.

result.processed.each{
    def queueEntry = QueueEntry.findById(it.id)&lt;&lt;&lt;START ADD&gt;&gt;&gt;
    Set dates = new HashSet&lt;Long&gt;()

    def children = QueueEntry.findAllByParent(queueEntry)

    for(QueueEntry qe : children){
        def f = new GregorianCalendar()
        f.setTimeInMillis(DateUtils.getClearedTime(qe.entryTimestamp))
        def l = new GregorianCalendar()
        l.setTimeInMillis(DateUtils.getClearedTime(qe.exitTimestamp))
        while(f &lt; l){
            if(f.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY &amp;&amp; f.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY){//only add weekdays
                dates.add(f.time.time)
            }
            def xx = new GregorianCalendar()
            xx.setTimeInMillis(f.time.next().time)
            f = xx
        }
        dates.add(l.time.time)
    } &lt;&lt;&lt;STOP ADD&gt;&gt;&gt;
    Set outsideDays = it.numberOfDaysOutsideCVB
    Set days = DateUtils.businessDaysBetweenDates(it.entryTimestamp, it.exitTimestamp)
    days.removeAll(outsideDays)
    days.removeAll(dates)
    turnTimes &lt;&lt; days.size()
}


The application is now crawling. I am obviously doing something wrong. When this is run for small data-sets it will complete slowly. On larger sets it doesn't finish. Prior to this change it was completing.
I found the logic of the set operations a bit hard confusing.  It appears that the goal is to take some set of days, named days, and remove entries from it.  So, start with days and remove entries from it.  You don't need the other sets named outsideDays and dates.

It's weird that it.numberOfDaysOutsideCVB returns a set rather than a number, as suggested by the method name.

The looping mechanism is cumbersome:


def xx = new GregorianCalendar()
xx.setTimeInMillis(f.time.next().time)
f = xx



The l day is always removed, regardless of the day of the week.  That deserves an explanatory comment.  Furthermore, f and l are somewhat cryptic variable names.

Set days = DateUtils.businessDaysBetweenDates(it.entryTimestamp, it.exitTimestamp)
days.removeAll(it.numberOfDaysOutsideCVB)

def children = QueueEntry.findAllByParent(QueueEntry.findById(it.id))
for (QueueEntry qe : children) {
    def entry = new GregorianCalendar()
    entry.setTimeInMillis(DateUtils.getClearedTime(qe.entryTimestamp))
    def exit = new GregorianCalendar()
    exit.setTimeInMillis(DateUtils.getClearedTime(qe.exitTimestamp))

    entry.upto(exit.previous()) { day -&gt;
        switch (day.get(Calendar.DAY_OF_WEEK)) {
          case Calendar.SATURDAY:
          case Calendar.SUNDAY:
            break
          default:
            days.remove(day.time.time)
        }
    }
    // Remove the last day regardless of day of week. (Why?)
    days.remove(exit.time.time)
}
turnTimes &lt;&lt; days.size()