Intersection between time

Asked

Viewed 170 times

2

I am in doubt about what to use in creating a film simulation project. So far I have a class Sessao:

package entidades;

import java.time.Duration;
import java.time.LocalTime;

public class Sessao {
    private String nomeFilme;
    private LocalTime horarioDoFilme;
    private Duration duracaoDoFilme;

    public Sessao(String nome, LocalTime horario, Duration duracao) {
        this.nomeFilme = nome;
        this.horarioDoFilme = horario;
        this.duracaoDoFilme = duracao;
    }

    public Duration getDuracaoDoFilme() {

        return duracaoDoFilme;
    }

    public void setDuracaoDoFilme(Duration duracaoDoFilme) {

        this.duracaoDoFilme = duracaoDoFilme;
    }

    public String getNomeFilme() {

        return nomeFilme;
    }

    public void setNomeFilme(String nomeFilme) {

        this.nomeFilme = nomeFilme;
    }

    public LocalTime getHorarioDoFilme() {

        return horarioDoFilme;
    }

    public void setHorarioDoFilme(LocalTime tempoFilme) {

        this.horarioDoFilme = tempoFilme;
    }



    public String toString() {
        return "\nFilme: " + nomeFilme +
                "\nHorário: " + horarioDoFilme +
                "\nDuração: " + duracaoDoFilme;
    }
}

In another project class I have the method adicionarSessao(). It receives an id from a room and obviously a new session. However, I can only add one session after testing if the duration of a new session does not interfere with the other.

I would like some help when it comes to finding out if there’s an intersection, because I’m not getting a logic for it.

1 answer

3


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.

  • 1

    Thank you very much, you helped me a lot.

  • Java has adopted something from Jodatime?

  • @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...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.