Example usage for org.joda.time Interval toDurationMillis

List of usage examples for org.joda.time Interval toDurationMillis

Introduction

In this page you can find the example usage for org.joda.time Interval toDurationMillis.

Prototype

public long toDurationMillis() 

Source Link

Document

Gets the duration of this time interval in milliseconds.

Usage

From source file:org.kuali.kpme.tklm.time.flsa.FlsaDay.java

License:Educational Community License

/**
  * This method determines if the provided LeaveBlock is applicable to this
  * FLSA day, and if so will add it to the applyList. It could be the case
  * that a LeaveBlock is on the boundary of the FLSA day so that only a
  * partial amount of the hours for that LeaveBlock will count towards this
  * day.//from   ww w  .  j  a  va2s . c om
  *
  * |---------+------------------+---------|
  * | Day 1   | Day 1/2 Boundary | Day 2   |
  * |---------+------------------+---------|
  * | Block 1 |             | Block 2      |
  * |---------+------------------+---------|
  *
  * The not so obvious ascii diagram above is intended to illustrate the case
  * where on day one you have 1 fully overlapping leave block (block1) and one
  * partially overlapping leave block (block2). Block 2 belongs to both FLSA
  * Day 1 and Day 2.
  *
 * @param block A leave block that we want to check and apply to this day.
 * @param applyList A list of leave blocks we want to add applicable leave blocks to.
 *
 * @return True if the block is applicable, false otherwise.  The return
 * value can be used as a quick exit for the setLeaveBlocks() method.
 *
 * TODO : Bucketing of partial FLSA days is still suspect, however real life examples of this are likely non-existent to rare.
 */
private boolean applyBlock(LeaveBlock block, List<LeaveBlock> applyList) {
    DateTime beginDateTime = new DateTime(block.getLeaveDate(), this.timeZone);
    DateTime endDateTime = new DateTime(block.getLeaveDate(), this.timeZone);

    if (beginDateTime.isAfter(flsaDateInterval.getEnd())) {
        return false;
    }

    Interval leaveBlockInterval = null;
    if (endDateTime.getMillis() > beginDateTime.getMillis()) {
        leaveBlockInterval = new Interval(beginDateTime, endDateTime);
    }

    Interval overlapInterval = flsaDateInterval.overlap(leaveBlockInterval);
    long overlap = (overlapInterval == null) ? 0L : overlapInterval.toDurationMillis();
    BigDecimal overlapHours = TKUtils.convertMillisToHours(overlap);
    if ((overlapHours.compareTo(BigDecimal.ZERO) == 0) && flsaDateInterval.contains(beginDateTime)
            && flsaDateInterval.contains(endDateTime)) {
        if (block.getLeaveAmount().negate().compareTo(BigDecimal.ZERO) > 0) {
            overlapHours = block.getLeaveAmount().negate();
        }
    }

    if (overlapHours.compareTo(BigDecimal.ZERO) > 0) {
        List<LeaveBlock> blocks = earnCodeToLeaveBlocks.get(block.getEarnCode());
        if (blocks == null) {
            blocks = new ArrayList<LeaveBlock>();
            earnCodeToLeaveBlocks.put(block.getEarnCode(), blocks);
        }
        blocks.add(block);
        applyList.add(block);
    }

    return true;
}

From source file:org.kuali.kpme.tklm.time.rules.shiftdifferential.service.ShiftDifferentialRuleServiceImpl.java

License:Educational Community License

@Override
public void processShiftDifferentialRules(TimesheetDocument timesheetDocument, TkTimeBlockAggregate aggregate) {
    DateTimeZone zone = HrServiceLocator.getTimezoneService().getUserTimezoneWithFallback();
    List<List<TimeBlock>> blockDays = aggregate.getDayTimeBlockList();
    DateTime periodStartDateTime = timesheetDocument.getCalendarEntry().getBeginPeriodLocalDateTime()
            .toDateTime(zone);// w ww .j  a va 2  s.c o m
    Map<Long, Set<ShiftDifferentialRule>> jobNumberToShifts = getJobNumberToShiftRuleMap(timesheetDocument);

    // If there are no shift differential rules, we have an early exit.
    if (jobNumberToShifts.isEmpty()) {
        return;
    }

    // Get the last day of the previous pay period. We need this to determine
    // if there are hours from the previous pay period that will effect the
    // shift rule on the first day of the currently-being-processed pay period.
    //
    // Will be set to null if not applicable.
    boolean previousPayPeriodPrevDay = true;
    Map<Long, List<TimeBlock>> jobNumberToTimeBlocksPreviousDay = getPreviousPayPeriodLastDayJobToTimeBlockMap(
            timesheetDocument, jobNumberToShifts);

    // We are going to look at the time blocks grouped by Days.
    //
    // This is a very large outer loop.
    for (int pos = 0; pos < blockDays.size(); pos++) {
        List<TimeBlock> blocks = blockDays.get(pos); // Timeblocks for this day.
        if (blocks.isEmpty())
            continue; // No Time blocks, no worries.

        DateTime currentDay = periodStartDateTime.plusDays(pos);
        Interval virtualDay = new Interval(currentDay, currentDay.plusHours(24));

        // Builds our JobNumber to TimeBlock for Current Day List.
        //
        // Shift Differential Rules are also grouped by Job number, this
        // provides a quick way to do the lookup / reference.
        // We don't need every time block, only the ones that will be
        // applicable to the shift rules.
        Map<Long, List<TimeBlock>> jobNumberToTimeBlocks = new HashMap<Long, List<TimeBlock>>();
        for (TimeBlock block : blocks) {
            Long jobNumber = block.getJobNumber();
            if (jobNumberToShifts.containsKey(jobNumber)) {
                List<TimeBlock> jblist = jobNumberToTimeBlocks.get(jobNumber);
                if (jblist == null) {
                    jblist = new ArrayList<TimeBlock>();
                    jobNumberToTimeBlocks.put(jobNumber, jblist);
                }
                jblist.add(block);
            }
        }

        // Large Outer Loop to look at applying the Shift Rules based on
        // the current JobNumber.
        //
        // This loop will handle previous day boundary time as well as the
        // current day.
        //
        // There is room for refactoring here!
        for (Map.Entry<Long, Set<ShiftDifferentialRule>> entry : jobNumberToShifts.entrySet()) {
            Set<ShiftDifferentialRule> shiftDifferentialRules = entry.getValue();
            // Obtain and sort our previous and current time blocks.
            List<TimeBlock> ruleTimeBlocksPrev = null;
            List<TimeBlock> ruleTimeBlocksCurr = jobNumberToTimeBlocks.get(entry.getKey());
            if (ruleTimeBlocksCurr != null && ruleTimeBlocksCurr.size() > 0) {
                if (jobNumberToTimeBlocksPreviousDay != null)
                    ruleTimeBlocksPrev = jobNumberToTimeBlocksPreviousDay.get(entry.getKey());
                if (ruleTimeBlocksPrev != null && ruleTimeBlocksPrev.size() > 0)
                    this.sortTimeBlocksInverse(ruleTimeBlocksPrev);
                this.sortTimeBlocksNatural(ruleTimeBlocksCurr);
            } else {
                // Skip to next job, there is nothing for this job
                // on this day, and because of this we don't care
                // about the previous day either.
                continue;
            }

            for (ShiftDifferentialRule rule : shiftDifferentialRules) {
                Set<String> fromEarnGroup = HrServiceLocator.getEarnCodeGroupService()
                        .getEarnCodeListForEarnCodeGroup(rule.getFromEarnGroup(), timesheetDocument
                                .getCalendarEntry().getBeginPeriodFullDateTime().toLocalDate());

                LocalTime ruleStart = new LocalTime(rule.getBeginTime(), zone);
                LocalTime ruleEnd = new LocalTime(rule.getEndTime(), zone);

                DateTime shiftEnd = ruleEnd.toDateTime(currentDay);
                DateTime shiftStart = ruleStart.toDateTime(currentDay);

                if (shiftEnd.isBefore(shiftStart) || shiftEnd.isEqual(shiftStart)) {
                    shiftEnd = shiftEnd.plusDays(1);
                }
                Interval shiftInterval = new Interval(shiftStart, shiftEnd);

                // Set up buckets to handle previous days time accumulations
                BigDecimal hoursBeforeVirtualDay = BigDecimal.ZERO;

                // Check current day first block to see if start time gap from virtual day start is greater than max gap
                // if so, we can skip the previous day checks.
                TimeBlock firstBlockOfCurrentDay = null;
                for (TimeBlock b : ruleTimeBlocksCurr) {
                    if (timeBlockHasEarnCode(fromEarnGroup, b)) {
                        firstBlockOfCurrentDay = b;
                        break;
                    }
                }

                // Previous Day :: We have prior block container of nonzero size, and the previous day is active.
                Interval previousDayShiftInterval = new Interval(shiftStart.minusDays(1),
                        shiftEnd.minusDays(1));

                // Blank initialization pointer for picking which interval to pass to applyPremium()
                Interval evalInterval = null;
                if (ruleTimeBlocksPrev != null && ruleTimeBlocksPrev.size() > 0
                        && dayIsRuleActive(currentDay.minusDays(1), rule)) {
                    // Simple heuristic to see if we even need to worry about
                    // the Shift rule for this set of data.
                    if (shiftEnd.isAfter(virtualDay.getEnd())) {
                        // Compare first block of previous day with first block of current day for max gaptitude.
                        TimeBlock firstBlockOfPreviousDay = null;
                        for (TimeBlock b : ruleTimeBlocksPrev) {
                            if (timeBlockHasEarnCode(fromEarnGroup, b)) {
                                firstBlockOfPreviousDay = b;
                                break;
                            }
                        }
                        // Only if we actually have at least one block.
                        // Adding Assumption: We must have both a valid current and previous block. Max Gap can not be more than a virtual day.
                        // If this assumption does not hold, additional logic will be needed to iteratively go back in time to figure out which
                        // blocks are valid.
                        if ((firstBlockOfPreviousDay != null) && (firstBlockOfCurrentDay != null)) {
                            Interval previousBlockInterval = new Interval(
                                    firstBlockOfPreviousDay.getEndDateTime().withZone(zone),
                                    firstBlockOfCurrentDay.getBeginDateTime().withZone(zone));
                            Duration blockGapDuration = previousBlockInterval.toDuration();
                            BigDecimal bgdHours = TKUtils.convertMillisToHours(blockGapDuration.getMillis());
                            // if maxGap is 0, ignore gaps and assign shift to time blocks within the hours
                            if (rule.getMaxGap().compareTo(BigDecimal.ZERO) == 0
                                    || bgdHours.compareTo(rule.getMaxGap()) <= 0) {
                                // If we are here, we know we have at least one valid time block to pull some hours forward from.

                                // These are inversely sorted.
                                for (int i = 0; i < ruleTimeBlocksPrev.size(); i++) {
                                    TimeBlock b = ruleTimeBlocksPrev.get(i);
                                    if (timeBlockHasEarnCode(fromEarnGroup, b)) {
                                        Interval blockInterval = new Interval(
                                                b.getBeginDateTime().withZone(zone),
                                                b.getEndDateTime().withZone(zone));

                                        // Calculate Block Gap, the duration between clock outs and clock ins of adjacent time blocks.
                                        if (previousBlockInterval != null) {
                                            blockGapDuration = new Duration(b.getEndDateTime().withZone(zone),
                                                    previousBlockInterval.getStart());
                                            bgdHours = TKUtils
                                                    .convertMillisToHours(blockGapDuration.getMillis());
                                        }

                                        // Check Gap, if good, sum hours, if maxGap is 0, ignore gaps
                                        if (rule.getMaxGap().compareTo(BigDecimal.ZERO) == 0
                                                || bgdHours.compareTo(rule.getMaxGap()) <= 0) {
                                            // Calculate Overlap and add it to hours before virtual day bucket.
                                            if (blockInterval.overlaps(previousDayShiftInterval)) {
                                                BigDecimal hrs = TKUtils.convertMillisToHours(blockInterval
                                                        .overlap(previousDayShiftInterval).toDurationMillis());
                                                hoursBeforeVirtualDay = hoursBeforeVirtualDay.add(hrs);
                                            }

                                        } else {
                                            // Time blocks are reverse sorted, we can jump out as soon as the max gap is exceeded.
                                            break;
                                        }

                                        previousBlockInterval = blockInterval;

                                    }
                                }
                            } else {
                                // DO NOTHING!
                            }
                        }
                    }
                }

                BigDecimal hoursToApply = BigDecimal.ZERO;
                BigDecimal hoursToApplyPrevious = BigDecimal.ZERO;
                // If the hours before virtual day are less than or equal to
                // min hours, we have already applied the time, so we don't
                // set hoursToApplyPrevious
                if (hoursBeforeVirtualDay.compareTo(rule.getMinHours()) <= 0) {
                    // we need to apply these hours.
                    hoursToApplyPrevious = hoursBeforeVirtualDay;
                }

                //  Current Day

                TimeBlock previous = null; // Previous Time Block
                List<TimeBlock> accumulatedBlocks = new ArrayList<TimeBlock>(); // TimeBlocks we MAY or MAY NOT apply Shift Premium to.
                List<Interval> accumulatedBlockIntervals = new ArrayList<Interval>(); // To save recompute time when checking timeblocks for application we store them as we create them.
                // Iterate over sorted list, checking time boundaries vs Shift Intervals.
                long accumulatedMillis = TKUtils.convertHoursToMillis(hoursBeforeVirtualDay);

                boolean previousDayOnly = false; // IF the rule is not active today, but was on the previous day, we need to still look at time blocks.
                if (!dayIsRuleActive(currentDay, rule)) {
                    if (dayIsRuleActive(currentDay.minusDays(1), rule)) {
                        previousDayOnly = true;
                    } else {
                        // Nothing to see here, move to next rule.
                        continue;
                    }

                }

                /*
                 * We will touch each time block and accumulate time blocks that are applicable to
                 * the current rule we are on.
                 */

                // These blocks are only used for detail application
                // We don't want to pass along the previous pay period,
                // because we don't want to modify the time blocks on that
                // period. If null is passed, time will be placed on the
                // first block of the first period if the previous period
                // block had influence.
                List<TimeBlock> previousBlocksFiltered = (previousPayPeriodPrevDay) ? null
                        : filterBlocksByApplicableEarnGroup(fromEarnGroup, ruleTimeBlocksPrev);

                for (TimeBlock current : ruleTimeBlocksCurr) {
                    if (!timeBlockHasEarnCode(fromEarnGroup, current)) {
                        // TODO: WorkSchedule considerations somewhere in here?
                        continue;
                    }

                    Interval blockInterval = new Interval(current.getBeginDateTime().withZone(zone),
                            current.getEndDateTime().withZone(zone));

                    // Check both Intervals, since the time blocks could still
                    // be applicable to the previous day.  These two intervals should
                    // not have any overlap.
                    if (previousDayShiftInterval.overlaps(shiftInterval)) {
                        LOG.error("Interval of greater than 24 hours created in the rules processing.");
                        return;
                        //                     throw new RuntimeException("Interval of greater than 24 hours created in the rules processing.");
                    }

                    // This block of code handles cases where you have time
                    // that spills to multiple days and a shift rule that
                    // has a valid window on multiple consecutive days. Time
                    // must be applied with the correct shift interval.
                    Interval overlap = previousDayShiftInterval.overlap(blockInterval);
                    evalInterval = previousDayShiftInterval;
                    if (overlap == null) {
                        if (hoursToApplyPrevious.compareTo(BigDecimal.ZERO) > 0) {
                            // we have hours from previous day, and the shift
                            // window is going to move to current day.
                            // Need to apply this now, and move window forward
                            // for current time block.
                            BigDecimal accumHours = TKUtils.convertMillisToHours(accumulatedMillis);
                            this.applyAccumulatedWrapper(accumHours, evalInterval, accumulatedBlockIntervals,
                                    accumulatedBlocks, previousBlocksFiltered, hoursToApplyPrevious,
                                    hoursToApply, rule);
                            accumulatedMillis = 0L; // reset accumulated hours..
                            hoursToApply = BigDecimal.ZERO;
                            hoursToApplyPrevious = BigDecimal.ZERO;
                        }

                        // Because of our position in the loop, when we are at this point,
                        // we know we've passed any previous day shift intervals, so we can
                        // determine if we should skip the current day based on the boolean
                        // we set earlier.
                        if (previousDayOnly) {
                            continue;
                        }

                        overlap = shiftInterval.overlap(blockInterval);
                        evalInterval = shiftInterval;
                    }

                    // Time bucketing and application as normal:
                    //
                    if (overlap != null) {
                        // There IS overlap.
                        if (previous != null) {
                            // only check max gap if max gap of rule is not 0
                            if (rule.getMaxGap().compareTo(BigDecimal.ZERO) != 0
                                    && exceedsMaxGap(previous, current, rule.getMaxGap())) {
                                BigDecimal accumHours = TKUtils.convertMillisToHours(accumulatedMillis);
                                this.applyAccumulatedWrapper(accumHours, evalInterval,
                                        accumulatedBlockIntervals, accumulatedBlocks, previousBlocksFiltered,
                                        hoursToApplyPrevious, hoursToApply, rule);
                                accumulatedMillis = 0L; // reset accumulated hours..
                                hoursToApply = BigDecimal.ZERO;
                                hoursToApplyPrevious = BigDecimal.ZERO;
                            } else {
                                long millis = overlap.toDurationMillis();
                                accumulatedMillis += millis;
                                hoursToApply = hoursToApply.add(TKUtils.convertMillisToHours(millis));
                            }
                        } else {
                            // Overlap shift at first time block.
                            long millis = overlap.toDurationMillis();
                            accumulatedMillis += millis;
                            hoursToApply = hoursToApply.add(TKUtils.convertMillisToHours(millis));
                        }
                        accumulatedBlocks.add(current);
                        accumulatedBlockIntervals.add(blockInterval);
                        previous = current; // current can still apply to next.
                    } else {
                        // No Overlap / Outside of Rule
                        if (previous != null) {
                            BigDecimal accumHours = TKUtils.convertMillisToHours(accumulatedMillis);
                            this.applyAccumulatedWrapper(accumHours, evalInterval, accumulatedBlockIntervals,
                                    accumulatedBlocks, previousBlocksFiltered, hoursToApplyPrevious,
                                    hoursToApply, rule);
                            accumulatedMillis = 0L; // reset accumulated hours..
                            hoursToApply = BigDecimal.ZERO;
                            hoursToApplyPrevious = BigDecimal.ZERO;
                        }
                    }

                }

                // All time blocks are iterated over, check for remainders.
                // Check containers for time, and apply if needed.
                BigDecimal accumHours = TKUtils.convertMillisToHours(accumulatedMillis);
                this.applyAccumulatedWrapper(accumHours, evalInterval, accumulatedBlockIntervals,
                        accumulatedBlocks, previousBlocksFiltered, hoursToApplyPrevious, hoursToApply, rule);
            }
        }
        //    Keep track of previous as we move day by day.
        jobNumberToTimeBlocksPreviousDay = jobNumberToTimeBlocks;
        previousPayPeriodPrevDay = false;
    }

}

From source file:org.kuali.kpme.tklm.time.rules.shiftdifferential.service.ShiftDifferentialRuleServiceImpl.java

License:Educational Community License

/**
 *
 * @param shift The shift interval - need to examine the time block to determine how many hours are eligible per block.
 * @param blockIntervals Intervals for each block present in the blocks list. Passed here to avoid re computation.
 * @param blocks The blocks we are applying hours to.
 * @param previousBlocks If present, this is the list of time blocks from a previous "day", on which the initial hours (from previous day) should be placed.
 * @param initialHours hours accumulated from a previous boundary that need to be applied here (NOT SUBJECT TO INTERVAL)
 * @param hours hours to apply/*from w  w w .  j  a  v a 2s .c o  m*/
 * @param earnCode what earn code to create time hour detail entry for.
 */
void applyPremium(Interval shift, List<Interval> blockIntervals, List<TimeBlock> blocks,
        List<TimeBlock> previousBlocks, BigDecimal initialHours, BigDecimal hours, String earnCode) {
    for (int i = 0; i < blocks.size(); i++) {
        TimeBlock b = blocks.get(i);

        // Only apply initial hours to the first timeblock.
        if (i == 0 && (initialHours.compareTo(BigDecimal.ZERO) > 0)) {
            // ONLY if they're on the same document ID, do we apply to previous,
            // otherwise we dump all on the current document.
            if (previousBlocks != null && previousBlocks.size() > 0
                    && previousBlocks.get(0).getDocumentId().equals(b.getDocumentId())) {
                for (TimeBlock pb : previousBlocks) {
                    BigDecimal lunchSub = this.negativeTimeHourDetailSum(pb); // A negative number
                    initialHours = BigDecimal.ZERO.max(initialHours.add(lunchSub)); // We don't want negative premium hours!
                    if (initialHours.compareTo(BigDecimal.ZERO) <= 0) // check here now as well, we may not have anything at all to apply.
                        break;

                    // Adjust hours on the block by the lunch sub hours, so we're not over applying.
                    BigDecimal hoursToApply = initialHours.min(pb.getHours().add(lunchSub));
                    addPremiumTimeHourDetail(pb, hoursToApply, earnCode);
                    initialHours = initialHours.subtract(hoursToApply, HrConstants.MATH_CONTEXT);
                    if (initialHours.compareTo(BigDecimal.ZERO) <= 0)
                        break;
                }
            } else {
                addPremiumTimeHourDetail(b, initialHours, earnCode);
            }
        }

        BigDecimal lunchSub = this.negativeTimeHourDetailSum(b); // A negative number
        hours = BigDecimal.ZERO.max(hours.add(lunchSub)); // We don't want negative premium hours!

        if (hours.compareTo(BigDecimal.ZERO) > 0) {
            Interval blockInterval = blockIntervals.get(i);
            Interval overlapInterval = shift.overlap(blockInterval);
            if (overlapInterval == null)
                continue;

            long overlap = overlapInterval.toDurationMillis();
            BigDecimal hoursMax = TKUtils.convertMillisToHours(overlap); // Maximum number of possible hours applicable for this time block and shift rule
            // Adjust this time block's hoursMax (below) by lunchSub to
            // make sure the time applied is the correct amount per block.
            BigDecimal hoursToApply = hours.min(hoursMax.add(lunchSub));

            addPremiumTimeHourDetail(b, hoursToApply, earnCode);
            hours = hours.subtract(hoursToApply, HrConstants.MATH_CONTEXT);
        }
    }
}

From source file:org.kuali.kpme.tklm.time.rules.shiftdifferential.shift.Shift.java

License:Educational Community License

public boolean exceedsMaxGap(Interval gapInterval, BigDecimal maxGap) {
    if (gapInterval == null) {
        return false;
    }//from w  ww  .  j av  a 2 s  . c  o  m
    BigDecimal gapMinutes = TKUtils.convertMillisToMinutes(gapInterval.toDurationMillis());

    return (gapMinutes.compareTo(maxGap) > 0);
}

From source file:org.oxymores.chronix.engine.SelfTriggerAgent.java

License:Apache License

protected long getNextLoopTime() {
    if (DateTime.now().compareTo(this.nextLoopVirtualTime) < 0) {
        Interval i = new Interval(DateTime.now(), this.nextLoopVirtualTime);
        return i.toDurationMillis();
    } else/*from   ww w.  j a v a 2 s .  c  om*/
        return 0;
}

From source file:org.sleuthkit.autopsy.timeline.TimeLineController.java

License:Open Source License

synchronized public void pushZoomOutTime() {
    final Interval timeRange = filteredEvents.timeRange().get();
    long toDurationMillis = timeRange.toDurationMillis() / 4;
    DateTime start = timeRange.getStart().minus(toDurationMillis);
    DateTime end = timeRange.getEnd().plus(toDurationMillis);
    pushTimeRange(new Interval(start, end));
}

From source file:org.sleuthkit.autopsy.timeline.TimeLineController.java

License:Open Source License

synchronized public void pushZoomInTime() {
    final Interval timeRange = filteredEvents.timeRange().get();
    long toDurationMillis = timeRange.toDurationMillis() / 4;
    DateTime start = timeRange.getStart().plus(toDurationMillis);
    DateTime end = timeRange.getEnd().minus(toDurationMillis);
    pushTimeRange(new Interval(start, end));
}

From source file:org.sleuthkit.autopsy.timeline.utils.IntervalUtils.java

License:Open Source License

static public Interval getIntervalAround(DateTime aroundInstant, ReadablePeriod period) {
    DateTime start = aroundInstant.minus(period);
    DateTime end = aroundInstant.plus(period);
    Interval range = new Interval(start, end);
    DateTime middleOf = IntervalUtils.middleOf(range);
    long halfRange = range.toDurationMillis() / 4;
    final Interval newInterval = new Interval(middleOf.minus(halfRange), middleOf.plus(halfRange));
    return newInterval;
}

From source file:org.yamj.common.tools.DateTimeTools.java

License:Open Source License

/**
 * Get the duration between tow Joda Dates
 *
 * @param start/*from   w w  w .  j a v  a  2s . c o m*/
 * @param end
 * @return the difference (in milliseconds) or -1 if "start" is after "end"
 */
public static long getDuration(DateTime start, DateTime end) {
    if (start.isBefore(end)) {
        Interval interval = new Interval(start, end);
        return interval.toDurationMillis();
    }
    return -1L;
}

From source file:udpserver.Task.java

public long getDuration() {
    try {//w  ww .jav  a  2  s .  c om

        Interval interval;
        if (endTime == null) {
            interval = new Interval(startTime, DateTime.now());
        } else {
            interval = new Interval(startTime, endTime);
        }
        return interval.toDurationMillis();
    } catch (IllegalArgumentException ex) {
        LOG.log(Level.WARNING, "Error : " + ex.getLocalizedMessage());
        return 0;
    }

}