tags:

views:

71

answers:

3

i'm trying to solve a seemingly simple problem, but just can't quite get my mind around it.

i have two times startTime and stopTime, which can be considered to be in the format: hh:mm:ss [24hr format].

Now given a third time - timeToTest - i need to find out if timeToTest lies between startTime and stopTime. There is no date information involved, other than just the times.

So for example - if i have startTime = '22:30:00' and stopTime = '03:30:00', then for timeToTest = '01:14:23', the test should return true.

I've tried a solution with java.util.Date by converting the times to milliseconds using getTime(), but with any interval which rolls over the 24 hr barrier, the logic fails.

I'm trying to build a solution using Java - but i believe the logic is language independent.

+2  A: 

You must add a "day" where "0" == current day, "1" == next day and so on. So in fact when stopTime == '03:30:00' it should be '27:30:00' (i.e. on the next day).

In your case, if the stopTime < startTime, then add 86400 seconds.

Aaron Digulla
aaron, i've tried the approach of adding a day to `stopTime` when it is smaller than `startTime`. however, the problem i face is - when do i decide to add a day to the `timeToTest`. For example, i should add a day to `timeToTest` when it is > `00:00:00` but < `stopTime`. but when it is < `00:00:00` i shouldn't. Also, since i need to run this logic over a data-set, i somehow feel putting so many checks and creating new Date objects might lead to a performance overhead.
anirvan
Well, if the time is after midnight, then it is on the next day. Your problem is that the "day" information is thrown away and there is no safe way to recreate it from the piece you're left with. The only safe solution is to keep this important fact when the data is created.
Aaron Digulla
Referring to performance: Start to worry about it when your solution works **and** is slow. Avoid premature optimization.
Aaron Digulla
+1  A: 

How about:

  • Find the next occurrence of the specified time after the start instant
  • Check whether that occurrence is before the end instant or not

The first step can probably be broken down pretty easily:

  • Is the specified time on/after the time of the start instant?
    • Yes: the next occurrence is that time on the same day as the start instant
    • No: the next occurrence is that time on the next day from the start instant

All of this is likely to be somewhat easier to write in Joda Time than using java.util.*, by the way :)

Jon Skeet
Indeed, Joda Time is very nice, and maybe the new JSR-310 https://jsr-310.dev.java.net/ implementation would solve many of the ugly problems with java.util.Date.
A. Ionescu
jon,well that's the logic i've been working on too. however, things like finding the next occurrence of the specified time is something i am finding hard or rather convoluted to figure out [using java.util.Date]. I'm looking into Joda, but haven't seen something which simplifies that task yet.
anirvan
@anirvan: Joda Time makes it easy to separate out the ideas of "LocalDateTime", "LocalDate" and "LocalTime". Things get confusing if you go for full DateTime values, where there could be DST changes involved... for example, occasionally you could have a start of 10pm and a finish of 5pm the next day - but not have a 1.30am between the two...
Jon Skeet
A: 

So the simplest solution i could come up with, sticking to plain old java.util.Date, is shown below:

    String d1 = "21:00:00";
    String d2 = "04:00:00";
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    String dToTest = "16:00:00";
    boolean isSplit = false, isWithin = false;

    Date dt1 = null, dt2 = null,  dt3 = null;

    dt1 = sdf.parse(d1);
    dt2 = sdf.parse(d2);
    dt3 = sdf.parse(dToTest);

    isSplit = (dt2.compareTo(dt1) < 0);
    System.out.println("[split]: " +isSplit);

    if (isSplit)
    {
        isWithin = (dt3.after(dt1) || dt3.before(dt2));
    }
    else
    {
        isWithin = (dt3.after(dt1) && dt3.before(dt2));
    }

    System.out.println("Is time within interval? " +isWithin);

feel free to point out any mistakes - would love to work and fix it.

anirvan