Example usage for org.joda.time DateTime secondOfDay

List of usage examples for org.joda.time DateTime secondOfDay

Introduction

In this page you can find the example usage for org.joda.time DateTime secondOfDay.

Prototype

public Property secondOfDay() 

Source Link

Document

Get the second of day property which provides access to advanced functionality.

Usage

From source file:net.tourbook.chart.ChartComponents.java

License:Open Source License

private void createDrawingData_X_History(final GraphDrawingData graphDrawingData,
        final double graphDefaultUnitD) {

    final ChartDataXSerie xData = graphDrawingData.getXData();
    final double scaleX = graphDrawingData.getScaleX();

    final long graphMaxValue = (long) xData.getOriginalMaxValue();
    final long graphDefaultUnit = (long) graphDefaultUnitD;

    // get start time without mills
    final DateTime tourStartTime = xData.getStartDateTime().minus(xData.getStartDateTime().getMillisOfSecond());
    final DateTime tourEndTime = tourStartTime.plus(graphMaxValue * 1000);

    long unitStart = tourStartTime.getMillis();
    long unitEnd = graphMaxValue;
    long firstUnitYear = tourStartTime.getYear();
    long lastUnitYear = tourEndTime.getYear();

    long roundedYearUnit = 0;
    long majorRoundedYearUnit = 0;
    final double dev1Year = scaleX * YEAR_IN_SECONDS;
    final double dev1Month = scaleX * MONTH_IN_SECONDS;

    //      System.out.println(UI.timeStampNano() + " \t");
    //      System.out.println(UI.timeStampNano() + " createDrawingData_X_History\t" + " start: " + tourStartTime);
    //      // TODO remove SYSTEM.OUT.PRINTLN

    final double devTitleVisibleUnit = _devAllMonthLabelWidth * 1.2;

    final boolean isYearRounded = dev1Year < _devYearLabelWidth * 4;
    if (isYearRounded) {

        /*/*from   ww  w .jav  a2s .  co m*/
         * adjust years to the rounded values
         */

        final double unitYears = (double) graphDefaultUnit / YEAR_IN_SECONDS;

        roundedYearUnit = Util.roundSimpleNumberUnits((long) unitYears);
        majorRoundedYearUnit = Util.getMajorSimpleNumberValue(roundedYearUnit);

        final long firstHistoryYear = tourStartTime.getYear();

        // decrease min value when it does not fit to unit borders
        final long yearMinRemainder = firstHistoryYear % roundedYearUnit;
        final long yearMinValue = firstHistoryYear - yearMinRemainder;

        final long yearMaxValue = lastUnitYear - (lastUnitYear % roundedYearUnit) + roundedYearUnit;

        unitStart = new DateTime((int) yearMinValue, 1, 1, 0, 0, 0, 0).getMillis();
        unitEnd = new DateTime((int) yearMaxValue, 12, 31, 23, 59, 59, 999).getMillis();
        firstUnitYear = yearMinValue;
        lastUnitYear = yearMaxValue;
    }

    /*
     * check if history units must be created, this is done only once for a tour to optimize it
     */
    if (unitStart != _historyUnitStart || unitEnd != _historyUnitDuration) {

        _historyUnitStart = unitStart;
        _historyUnitDuration = unitEnd;

        createHistoryUnits((int) firstUnitYear, (int) lastUnitYear);
    }

    graphDrawingData.setXUnitTextPos(GraphDrawingData.X_UNIT_TEXT_POS_CENTER);
    graphDrawingData.setIsXUnitOverlapChecked(true);
    graphDrawingData.setIsCheckUnitBorderOverlap(false);

    final HistoryTitle historyTitle = new HistoryTitle();
    xData.setHistoryTitle(historyTitle);

    // hide default unit
    xData.setUnitLabel(UI.EMPTY_STRING);

    final double devGraphXOffset = componentGraph.getXXDevViewPortLeftBorder();
    final int devVisibleWidth = getDevVisibleChartWidth();

    final long graphLeftBorder = (long) (devGraphXOffset / scaleX);
    final long graphRightBorder = (long) ((devGraphXOffset + devVisibleWidth) / scaleX);

    final ArrayList<ChartUnit> xUnits = graphDrawingData.getXUnits();
    final ArrayList<ChartUnit> xUnitTitles = new ArrayList<ChartUnit>();

    final ArrayList<Long> titleValueStart = historyTitle.graphStart = new ArrayList<Long>();
    final ArrayList<Long> titleValueEnd = historyTitle.graphEnd = new ArrayList<Long>();
    final ArrayList<String> titleText = historyTitle.titleText = new ArrayList<String>();

    final boolean isTimeSerieWithTimeZoneAdjustment = xData.isTimeSerieWithTimeZoneAdjustment();

    //      DateTime graphTime = tourStartTime.plus(graphLeftBorder * 1000);
    //      if (isTimeSerieWithTimeZoneAdjustment) {
    //         if (graphTime.getMillis() > UI.beforeCET) {
    //            graphTime = graphTime.minus(UI.BERLIN_HISTORY_ADJUSTMENT * 1000);
    //         }
    //      }
    //
    ////      final int graphSecondsOfDay = graphTime.getSecondOfDay();
    ////      final DateTime graphNextDay = graphTime.plus((DAY_IN_SECONDS - graphSecondsOfDay) * 1000);
    //
    //      System.out.println(UI.timeStampNano());
    //      System.out.println(UI.timeStampNano() + " tourStartTime " + tourStartTime);
    //      System.out.println(UI.timeStampNano() + " graphTime     " + graphTime);
    ////      System.out.println(UI.timeStampNano() + " graphNextDay  " + graphNextDay);
    //      System.out.println(UI.timeStampNano());
    //      // TODO remove SYSTEM.OUT.PRINTLN

    if (isYearRounded) {

        /*
         * create units for rounded years
         */

        //         System.out.println(UI.timeStampNano() + "\trounded years\t");
        //         // TODO remove SYSTEM.OUT.PRINTLN

        graphDrawingData.setXUnitTextPos(GraphDrawingData.X_UNIT_TEXT_POS_LEFT);

        int historyYearIndex = 0;

        /*
         * start unit at the first day of the first year at 0:00:00, this is necessary that the
         * unit is positioned exactly
         */
        final int startDOY = tourStartTime.getDayOfYear();
        final int startDaySeconds = tourStartTime.secondOfDay().get();

        final int startYear = tourStartTime.getYear();

        int yearIndex = 0;
        long graphYearOffset = 0;
        while (startYear > _historyYears[yearIndex]) {
            graphYearOffset += _historyDOY[yearIndex++] * DAY_IN_SECONDS;
        }

        long graphValue = -startDOY * DAY_IN_SECONDS - startDaySeconds - graphYearOffset;

        // loop: years
        while (graphValue <= graphMaxValue) {

            long graphUnit = 0;

            for (int unitIndex = 0; unitIndex < roundedYearUnit; unitIndex++) {

                final int unitYearIndex = historyYearIndex + unitIndex;

                // graph unit = rounded years
                graphUnit += _historyDOY[unitYearIndex] * DAY_IN_SECONDS;
            }

            if (graphValue < graphLeftBorder - graphUnit //
            //
            // ensure it's 366 days
                    - DAY_IN_SECONDS) {

                // advance to the next unit
                graphValue += graphUnit;
                historyYearIndex += roundedYearUnit;

                continue;
            }

            if (graphValue > graphRightBorder) {
                break;
            }

            /*
             * draw year tick
             */
            final int yearValue = _historyYears[historyYearIndex];

            final boolean isMajorValue = yearValue % majorRoundedYearUnit == 0;

            xUnits.add(new ChartUnit(graphValue + DAY_IN_SECONDS, UI.EMPTY_STRING, isMajorValue));

            /*
             * draw title
             */
            titleValueStart.add(graphValue);
            titleValueEnd.add(graphValue + graphUnit - 1);
            titleText.add(Integer.toString(yearValue));

            // advance to the next rounded unit
            graphValue += graphUnit;
            historyYearIndex += roundedYearUnit;
        }

    } else if (dev1Year < _devAllMonthLabelWidth * 12) {

        /*
         * create units for year/month
         */

        //         System.out.println(UI.timeStampNano() + "\tyear/month\t");
        //         // TODO remove SYSTEM.OUT.PRINTLN

        graphDrawingData.setTitleTextPos(GraphDrawingData.X_UNIT_TEXT_POS_CENTER);
        graphDrawingData.setXUnitTextPos(GraphDrawingData.X_UNIT_TEXT_POS_CENTER);

        int historyYearIndex = 0;

        // start unit at the first day of the first year at 0:00:00
        final int startDOY = tourStartTime.getDayOfYear();
        final int startSeconds = tourStartTime.secondOfDay().get();
        long graphValue = -startDOY * DAY_IN_SECONDS - startSeconds;

        // loop: years
        while (graphValue <= graphMaxValue) {

            // graph unit = 1 year
            final long graphUnit = _historyDOY[historyYearIndex] * DAY_IN_SECONDS;

            if (graphValue < graphLeftBorder - graphUnit //
            //
            // ensure it's 366 days
                    - DAY_IN_SECONDS) {

                // advance to the next unit
                graphValue += graphUnit;
                historyYearIndex++;

                continue;
            }

            if (graphValue > graphRightBorder) {
                break;
            }

            final int devUnitWidth = (int) (scaleX * graphUnit);
            final int[] historyMonthDays = _historyMonths[historyYearIndex];

            /*
             * draw year tick
             */
            xUnits.add(new ChartUnit(graphValue + DAY_IN_SECONDS, UI.EMPTY_STRING, true));

            /*
             * draw year title
             */
            {
                final String yearLabel = Integer.toString(_historyYears[historyYearIndex]);

                /*
                 * get number of repeated year labels within a year unit
                 */
                int repeatedMonths = 1;

                while (true) {
                    if (devUnitWidth / repeatedMonths < devTitleVisibleUnit) {
                        break;
                    }
                    repeatedMonths++;
                }

                // ensure array size is big enough (*2)
                final int[] monthStarts = new int[repeatedMonths * 2];
                final int[] monthEnds = new int[repeatedMonths * 2];
                final int monthRepeats = 12 / repeatedMonths;

                int yearMonthDOY = 0;
                int repeatIndex = 0;

                for (int monthIndex = 0; monthIndex < 12; monthIndex++) {

                    final int monthDays = historyMonthDays[monthIndex];

                    if (monthIndex % monthRepeats == 0) {

                        if (repeatIndex > 0) {
                            monthEnds[repeatIndex - 1] = yearMonthDOY;
                        }

                        monthStarts[repeatIndex] = yearMonthDOY;

                        repeatIndex++;
                    }

                    yearMonthDOY += monthDays;
                }
                monthEnds[repeatIndex - 1] = yearMonthDOY;

                for (int repeatIndex2 = 0; repeatIndex2 < monthStarts.length; repeatIndex2++) {

                    final int monthStart = monthStarts[repeatIndex2];
                    final int monthEnd = monthEnds[repeatIndex2];

                    // skip invalid entries
                    if (monthStart == 0 && monthEnd == 0) {
                        break;
                    }

                    titleValueStart.add(graphValue + monthStart * DAY_IN_SECONDS + DAY_IN_SECONDS);
                    titleValueEnd.add(graphValue + monthEnd * DAY_IN_SECONDS + DAY_IN_SECONDS);

                    titleText.add(yearLabel);
                }
            }

            /*
             * draw x-axis units
             */

            if (devUnitWidth >= _devAllMonthLabelWidth * 1.2) {

                createHistoryMonthUnits_Months(xUnits, historyMonthDays, graphValue, 1, 12, true);

            } else if (devUnitWidth >= _devAllMonthLabelWidth * 1) {

                createHistoryMonthUnits_Months(xUnits, historyMonthDays, graphValue, 3, 0, false);

            } else if (devUnitWidth >= _devAllMonthLabelWidth * 0.7) {

                createHistoryMonthUnits_Months(xUnits, historyMonthDays, graphValue, 6, 0, false);
            }

            // advance to the next unit
            graphValue += graphUnit;
            historyYearIndex++;
        }

    } else if (dev1Month < _devAllMonthLabelWidth * 30) {

        /*
         * create units for month/day
         */

        //         System.out.println(UI.timeStampNano() + "\tmonth/day");
        //         // TODO remove SYSTEM.OUT.PRINTLN

        graphDrawingData.setTitleTextPos(GraphDrawingData.X_UNIT_TEXT_POS_CENTER);

        int historyYearIndex = 0;

        // start unit at the first day of the first year at 0:00:00
        final int startDOY = tourStartTime.getDayOfYear();
        final int startSeconds = tourStartTime.secondOfDay().get();
        long graphValue = -startDOY * DAY_IN_SECONDS - startSeconds;

        monthLoop:

        // loop: months
        while (graphValue <= graphMaxValue) {

            final int[] yearMonths = _historyMonths[historyYearIndex];

            for (int monthIndex = 0; monthIndex < yearMonths.length; monthIndex++) {

                final int monthDays = yearMonths[monthIndex];

                // graph unit = 1 month
                final long graphUnit = monthDays * DAY_IN_SECONDS;

                if (graphValue < graphLeftBorder - graphUnit) {

                    // advance to the next month unit
                    graphValue += graphUnit;

                    continue;
                }

                if (graphValue > graphRightBorder) {
                    break monthLoop;
                }

                /*
                 * draw month tick
                 */
                xUnits.add(new ChartUnit(graphValue + DAY_IN_SECONDS, UI.EMPTY_STRING, true));

                /*
                 * create title units
                 */
                {
                    final String monthTitle = _monthLabels[monthIndex] + UI.SPACE2
                            + Integer.toString(_historyYears[historyYearIndex]);

                    // get number of repeated labels within one graph unit
                    int repeatedDays = 1;
                    final int devUnitWidth = (int) (scaleX * graphUnit);

                    while (true) {
                        if (devUnitWidth / repeatedDays < devTitleVisibleUnit) {
                            break;
                        }
                        repeatedDays++;
                    }

                    // ensure array size is big enough (*2)
                    final int[] dayStarts = new int[repeatedDays * 2];
                    final int[] dayEnds = new int[repeatedDays * 2];
                    final int repeatedDayUnit = monthDays / repeatedDays;

                    int dayStartEnd = 0;
                    int repeatIndex = 0;

                    for (int dayIndex = 0; dayIndex < monthDays; dayIndex++) {

                        if (dayIndex % repeatedDayUnit == 0) {

                            if (repeatIndex > 0) {
                                dayEnds[repeatIndex - 1] = dayStartEnd;
                            }

                            dayStarts[repeatIndex] = dayStartEnd;

                            repeatIndex++;
                        }

                        dayStartEnd += 1;
                    }
                    dayEnds[repeatIndex - 1] = dayStartEnd;

                    for (int repeatIndex2 = 0; repeatIndex2 < dayStarts.length; repeatIndex2++) {

                        final int dayStart = dayStarts[repeatIndex2];
                        final int dayEnd = dayEnds[repeatIndex2];

                        // skip invalid entries
                        if (dayStart == 0 && dayEnd == 0) {
                            break;
                        }

                        titleValueStart.add(graphValue + dayStart * DAY_IN_SECONDS + DAY_IN_SECONDS);
                        titleValueEnd.add(graphValue + dayEnd * DAY_IN_SECONDS + DAY_IN_SECONDS);
                        titleText.add(monthTitle);
                    }
                }

                /*
                 * draw x-axis units: day number in month
                 */
                final double unitDays = (double) graphDefaultUnit / DAY_IN_SECONDS;

                final int roundedDayUnit = Util.roundSimpleNumberUnits((long) unitDays);

                if (roundedDayUnit == 1) {
                    graphDrawingData.setXUnitTextPos(GraphDrawingData.X_UNIT_TEXT_POS_CENTER);
                } else {
                    graphDrawingData.setXUnitTextPos(GraphDrawingData.X_UNIT_TEXT_POS_LEFT);
                }

                int dayNo = roundedDayUnit;
                while (dayNo <= monthDays) {

                    xUnits.add(new ChartUnit(//
                            graphValue + (dayNo * DAY_IN_SECONDS), Integer.toString(dayNo), false));

                    dayNo += roundedDayUnit;
                }

                // advance to the next month unit
                graphValue += graphUnit;
            }

            historyYearIndex++;
        }

    } else {

        /*
         * create units for day/seconds
         */

        //         System.out.println(UI.timeStampNano() + " day/seconds");
        //         // TODO remove SYSTEM.OUT.PRINTLN

        graphDrawingData.setTitleTextPos(GraphDrawingData.X_UNIT_TEXT_POS_CENTER);
        graphDrawingData.setXUnitTextPos(GraphDrawingData.X_UNIT_TEXT_POS_LEFT);

        final long graphUnit = Util.roundTime24h(graphDefaultUnit);
        final long majorUnit = Util.getMajorTimeValue24(graphUnit);

        final int startSeconds = tourStartTime.secondOfDay().get();
        final long startUnitOffset = startSeconds % graphUnit;

        // decrease min value when it does not fit to unit borders, !!! VERY IMPORTANT !!!
        final long graphValueStart = graphLeftBorder - graphLeftBorder % graphUnit;

        final long graphMaxVisibleValue = graphRightBorder + graphUnit;
        long graphValue = graphValueStart;

        /*
         * create x-axis units
         */
        while (graphValue <= graphMaxVisibleValue) {

            // create unit value/label
            final long unitValueAdjusted = graphValue - startUnitOffset;
            final long unitValueStart = unitValueAdjusted + startSeconds;

            final long unitValue = unitValueStart % DAY_IN_SECONDS;

            final String unitLabel = net.tourbook.chart.Util.format_hh_mm_ss_Optional(unitValue);

            final boolean isMajorValue = unitValue % majorUnit == 0;

            xUnits.add(new ChartUnit(unitValueAdjusted, unitLabel, isMajorValue));

            graphValue += graphUnit;
        }

        /*
         * create dummy units before and after the real units that the title is displayed also
         * at the border, title is displayed between major units
         */
        final int numberOfSmallUnits = (int) (majorUnit / graphUnit);
        long titleUnitStart = (long) xUnits.get(0).value;

        for (int unitIndex = numberOfSmallUnits; unitIndex > 0; unitIndex--) {

            final long unitValueAdjusted = titleUnitStart - (graphUnit * unitIndex);

            final long unitValue = (unitValueAdjusted + startSeconds) % DAY_IN_SECONDS;
            final boolean isMajorValue = unitValue % majorUnit == 0;

            final String unitLabel = net.tourbook.chart.Util.format_hh_mm_ss_Optional(unitValue);

            xUnitTitles.add(new ChartUnit(unitValueAdjusted, unitLabel, isMajorValue));
        }

        xUnitTitles.addAll(xUnits);

        titleUnitStart = (long) xUnitTitles.get(xUnitTitles.size() - 1).value;

        for (int unitIndex = 1; unitIndex < numberOfSmallUnits * 1; unitIndex++) {

            final long unitValueAdjusted = titleUnitStart + (graphUnit * unitIndex);

            final long unitValue = (unitValueAdjusted + startSeconds) % DAY_IN_SECONDS;
            final boolean isMajorValue = unitValue % majorUnit == 0;

            final String unitLabel = net.tourbook.chart.Util.format_hh_mm_ss_Optional(unitValue);

            xUnitTitles.add(new ChartUnit(unitValueAdjusted, unitLabel, isMajorValue));
        }

        /*
         * create title units
         */
        long prevGraphUnitValue = Long.MIN_VALUE;

        for (int unitIndex = 0; unitIndex < xUnitTitles.size(); unitIndex++) {

            final ChartUnit chartUnit = xUnitTitles.get(unitIndex);
            if (chartUnit.isMajorValue) {

                final long currentGraphUnitValue = (long) chartUnit.value;

                if (prevGraphUnitValue != Long.MIN_VALUE) {

                    titleValueStart.add(prevGraphUnitValue);
                    titleValueEnd.add(currentGraphUnitValue - 1);

                    long graphDay = tourStartTime.getMillis() + prevGraphUnitValue * 1000;

                    if (isTimeSerieWithTimeZoneAdjustment) {

                        if (graphDay > UI.beforeCET) {
                            graphDay -= UI.BERLIN_HISTORY_ADJUSTMENT * 1000;
                        }
                    }

                    final String dayTitle = _dtFormatter.print(graphDay);

                    titleText.add(dayTitle);
                }

                prevGraphUnitValue = currentGraphUnitValue;
            }
        }
    }

    //      System.out.println(UI.timeStampNano() + " \t");
    //
    //      for (final ChartUnit xUnit : xUnits) {
    //         System.out.println(UI.timeStampNano() + " \t" + xUnit);
    //         // TODO remove SYSTEM.OUT.PRINTLN
    //      }
    //
    //
    //      for (final ChartUnit xUnit : xUnitTitles) {
    //         System.out.println(UI.timeStampNano() + " \t" + xUnit);
    //         // TODO remove SYSTEM.OUT.PRINTLN
    //      }
    //
    //      for (int unitIndex = 0; unitIndex < titleText.size(); unitIndex++) {
    //
    //         System.out.println(UI.timeStampNano()
    //               + ("\t" + titleText.get(unitIndex))
    //               + ("\t" + (long) ((long) (titleValueStart.get(unitIndex) * scaleX) - devGraphXOffset))
    //               + ("\t" + (long) ((long) (titleValueEnd.get(unitIndex) * scaleX) - devGraphXOffset))
    //               + ("\t" + titleValueStart.get(unitIndex))
    //               + ("\t" + titleValueEnd.get(unitIndex))
    //         //
    //               );
    //         // TODO remove SYSTEM.OUT.PRINTLN
    //      }
}

From source file:org.kuali.kpme.tklm.utils.TkTestUtils.java

License:Educational Community License

public static Map<DateTime, BigDecimal> getDateToHoursMap(TimeBlock timeBlock, TimeHourDetail timeHourDetail) {
    Map<DateTime, BigDecimal> dateToHoursMap = new HashMap<DateTime, BigDecimal>();
    DateTime beginTime = timeBlock.getBeginDateTime();
    DateTime endTime = timeBlock.getEndDateTime();

    Days d = Days.daysBetween(beginTime, endTime);
    int numberOfDays = d.getDays();
    if (numberOfDays < 1) {
        dateToHoursMap.put(timeBlock.getBeginDateTime(), timeHourDetail.getHours());
        return dateToHoursMap;
    }/*from  w  ww.  jav a 2s  . c o m*/
    DateTime currentTime = beginTime;
    for (int i = 0; i < numberOfDays; i++) {
        DateTime nextDayAtMidnight = currentTime.plusDays(1);
        nextDayAtMidnight = nextDayAtMidnight.hourOfDay().setCopy(12);
        nextDayAtMidnight = nextDayAtMidnight.minuteOfDay().setCopy(0);
        nextDayAtMidnight = nextDayAtMidnight.secondOfDay().setCopy(0);
        nextDayAtMidnight = nextDayAtMidnight.millisOfSecond().setCopy(0);
        Duration dur = new Duration(currentTime, nextDayAtMidnight);
        long duration = dur.getStandardSeconds();
        BigDecimal hrs = new BigDecimal(duration / 3600, HrConstants.MATH_CONTEXT);
        dateToHoursMap.put(currentTime, hrs);
        currentTime = nextDayAtMidnight;
    }
    Duration dur = new Duration(currentTime, endTime);
    long duration = dur.getStandardSeconds();
    BigDecimal hrs = new BigDecimal(duration / 3600, HrConstants.MATH_CONTEXT);
    dateToHoursMap.put(currentTime, hrs);

    return dateToHoursMap;
}

From source file:org.kuali.rice.core.api.mo.common.active.InactivatableFromToUtils.java

License:Educational Community License

private static boolean computeActive(DateTime activeFromDate, DateTime activeToDate, DateTime activeAsOfDate) {
    // the precision of this check should be to the second, not milliseconds, so we want to chop off any
    // milliseconds and do a ceiling of our seconds. Sometimes changes are made in near real time after a record
    // becomes activated or inactivated so we want to have the best result possible if they are still within the
    // same second, so we essentially always round up to ensure that this check will never fail in high throughput
    // environments
    activeAsOfDate = activeAsOfDate.secondOfDay().roundCeilingCopy();
    return (activeFromDate == null || activeAsOfDate.getMillis() >= activeFromDate.getMillis())
            && (activeToDate == null || activeAsOfDate.getMillis() < activeToDate.getMillis());
}

From source file:org.kuali.rice.kim.api.common.history.HistoryQueryUtils.java

License:Educational Community License

public static Predicate between(String startField, String endField, DateTime asOfDate) {
    // the precision of this check should be to the second, not milliseconds, so we want to chop off any
    // milliseconds and do a ceiling of our seconds. Sometimes changes are made in near real time after a record
    // becomes activated or inactivated so we want to have the best result possible if they are still within the
    // same second, so we essentially always round up to ensure that this check will never fail in high throughput
    // environments
    asOfDate = asOfDate.secondOfDay().roundCeilingCopy();
    return and(or(isNull(startField), lessThanOrEqual(startField, asOfDate.toDate())),
            or(isNull(endField), greaterThan(endField, asOfDate.toDate())));
}