The basic idea is to get the time the session ends (adding the duration to the initial time), and check if the end is after the beginning of the other session (if it is, they interfere with each other).
Then in class Sessao
you can add a method that does this check:
public class Sessao {
public boolean interfere(Sessao outra) {
Sessao antes, depois;
if (this.horarioDoFilme.isBefore(outra.horarioDoFilme)) {
antes = this;
depois = outra;
} else {
antes = outra;
depois = this;
}
return antes
// calcula horário de término = horário de início + duração
.horarioDoFilme.plus(antes.duracaoDoFilme)
// verifica se o término é depois do início da sessão seguinte
.isAfter(depois.horarioDoFilme);
}
}
First I see which session starts before, using the method isBefore
.
Then I calculate the end time of the session that starts before (using the method plus
to add the duration to the initial time) and check if this end occurs after the other session has already started (with the method isAfter
).
If the first session ends after the other one has already started, it is because they interfere with each other (and in this case, the method interfere
returns true
). Testing:
// filme com 2 horas de duração, começa as 14h
Sessao s1 = new Sessao("A", LocalTime.of(14, 0), Duration.ofHours(2));
// filme com 2 horas de duração, começa as 15h
Sessao s2 = new Sessao("B", LocalTime.of(15, 0), Duration.ofHours(2));
// filme com 2 horas de duração, começa as 17h
Sessao s3 = new Sessao("C", LocalTime.of(17, 0), Duration.ofHours(2));
System.out.println(s1.interfere(s2)); // true
System.out.println(s1.interfere(s3)); // false
System.out.println(s2.interfere(s3)); // false
Notice that s2
ends at 5 pm, which is the same time as s3
starts. The above algorithm considers that if it ends at exactly the same time, then there is no interference.
But if you want to consider that "exactly the same time" is also interference, just change the return method interfere
for:
return ! antes
// calcula horário de término = horário de início + duração
.horarioDoFilme.plus(antes.duracaoDoFilme)
// verifica se o término é depois do início da sessão seguinte
.isBefore(depois.horarioDoFilme);
Now I use !
(who is the denial operator) and switched the call to isBefore
. That is, now the logic is to check whether the first session nay ends before the beginning of the other (which means either it ends at the same time or after). Using this implementation, s2.interfere(s3)
returns true
.
In this case, to add a new session, you would have to check that it does not interfere with any other session (i.e., you would have to call the method intefere
several times, comparing the new session with all other existing).
Another detail is that LocalTime
only information about the time, but not about the date. That is, if the session starts around midnight, it may end in the early hours of the next day, and the above comparisons fail. Ex: if it starts 11 at night and lasts 2 hours, the above code fails because the end time is 1 am, which a LocalTime
considers that it is before eleven in the evening, since this class does not take into account the day.
If you want to consider these cases as well, I suggest changing the session times to LocalDateTime
(that has date and time, so when adding the duration, the dates are correctly adjusted for the next day, if necessary), or ZonedDateTime
, if you also want to consider the time zone and more complicated cases such as daylight savings time changes. Both have the methods plus
to sum up a duration, and isAfter
and isBefore
to make comparisons.
Thank you very much, you helped me a lot.
– Diogo Marcelo
Java has adopted something from Jodatime?
– Maniero
@Maniero According to Stephen Colebourne himself, some ideas and concepts were taken advantage of, but other things he considered "wrong" or bad, he took the opportunity to correct. More details on his blog, here and here. He even says the API
java.time
would be more "inspired" in Joda-Time, than a simple copy...– hkotsubo