Date range in date range

Having spent my fair share of time mucking around with … well, time…I can tell you that I’d prefer to let someone else do the work for me.

To that end, if you’re will to give it a go, I’d take a look at JodaTime

Basically, what this example does it creates a series of Intervals. One is the “period”, or week of year (starting at Monday and finishing on Sunday).

One Interval is an overlapping interval, which spans one week before and one week after the “period”, the other is a single day Interval within the “period”

import org.joda.time.Interval;
import org.joda.time.MutableDateTime;
import org.joda.time.Period;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.DateTimeFormatterBuilder;
import org.joda.time.format.DateTimeParser;

public class TestTimeInterval {

    public static void main(String[] args) {

        DateTimeFormatter formatter = new DateTimeFormatterBuilder().
                        appendDayOfMonth(2).appendLiteral(" ").
                        appendDayOfWeekText().appendLiteral(" ").
                        appendMonthOfYearText().appendLiteral(" ").
                        appendYear(2, 2).
                        toFormatter();

        // Last week
        MutableDateTime targetStart = MutableDateTime.now();
        targetStart.setDayOfWeek(1);
        targetStart.addDays(-6);

        // Next week
        MutableDateTime targetEnd = MutableDateTime.now();
        targetEnd.setDayOfWeek(7);
        targetEnd.addDays(7);

        System.out.println("Target range = " + formatter.print(targetStart) + " to " + formatter.print(targetEnd));
        Interval targetInterval = new Interval(targetStart, targetEnd);

        // This week
        MutableDateTime start = MutableDateTime.now();
        start.setDayOfWeek(1);

        MutableDateTime end = MutableDateTime.now();
        end.setDayOfWeek(7);

        Interval interval = new Interval(start, end);

        System.out.println("Interval range = " + formatter.print(start) + " to " + formatter.print(end));
        System.out.println("Contains interval = " + targetInterval.contains(interval));

        // Last week
        targetStart = DateTime.now();

        // Next week
        targetEnd = DateTime.now();

        System.out.println("Target range = " + formatter.print(targetStart) + " to " + formatter.print(targetEnd));
        targetInterval = new Interval(targetStart, targetEnd);
        System.out.println("Contains interval = " + interval.contains(targetInterval));
    }

}

Which outputs…

Target range = 10 Tuesday December 2013 to 29 Sunday December 2013
Period range = 16 Monday December 2013 to 22 Sunday December 2013
Contains period = true
Target range = 19 Thursday December 2013 to 19 Thursday December 2013
Contains period = true

What you end up with only need to check the period interval in two ways.

  1. To check if the “period” is within the supplied Interval and
  2. If the supplied Interval is within the “period”…

For example…

 if (period.contains(interval) || interval.contains(period)) {
     // Match...
 }

Now, there is a whole lot of other things to consider, like, if time is not important to the Intervals, you’ll want to zero the time (the start the period should be midnight/morning and the end should midnight evening) so you maximums the catch area

Updated making better use of the JodaTime libraries

@BasilBourque was able to highlight some issues with the original example, which I’ve updated and tested accordingly. Thanks @BasilBourque

While simular to the original, it makes better use the JodaTime libraries

public static void newWay() {

    DateTimeFormatter formatter = new DateTimeFormatterBuilder().
            appendDayOfMonth(2).appendLiteral(" ").
            appendDayOfWeekText().appendLiteral(" ").
            appendMonthOfYearText().appendLiteral(" ").
            appendYear(2, 2).
            toFormatter();

    // Last week
    DateTime targetStart = DateTime.now(DateTimeZone.getDefault()).
            withDayOfWeek(DateTimeConstants.MONDAY).
            minusDays(6);
    //MutableDateTime targetStart = MutableDateTime.now();
    //targetStart.setDayOfWeek(1);
    //targetStart.addDays(-6);

    // Next week
    DateTime targetEnd = DateTime.now(DateTimeZone.getDefault()).
            withDayOfWeek(DateTimeConstants.SUNDAY).
            plusDays(7);
    //MutableDateTime targetEnd = MutableDateTime.now();
    //targetEnd.setDayOfWeek(7);
    //targetEnd.addDays(7);

    System.out.println("Target range = " + formatter.print(targetStart) + " to " + formatter.print(targetEnd));
    Interval targetInterval = new Interval(targetStart, targetEnd);

    // This week
    DateTime start = DateTime.now(DateTimeZone.getDefault()).
            withDayOfWeek(DateTimeConstants.MONDAY);
    //MutableDateTime start = MutableDateTime.now();
    //start.setDayOfWeek(1);

    DateTime end = DateTime.now(DateTimeZone.getDefault()).
            withDayOfWeek(DateTimeConstants.SUNDAY);
    //MutableDateTime end = MutableDateTime.now();
    //end.setDayOfWeek(7);

    Interval interval = new Interval(start, end);

    System.out.println("Period range = " + formatter.print(start) + " to " + formatter.print(end));

    System.out.println("Contains period = " + targetInterval.contains(interval));

    // Last week
    targetStart = DateTime.now();

    // Next week
    targetEnd = DateTime.now();

    System.out.println("Target range = " + formatter.print(targetStart) + " to " + formatter.print(targetEnd));
    targetInterval = new Interval(targetStart, targetEnd);
    System.out.println("Contains period = " + interval.contains(targetInterval));

}

Leave a Comment