Compare dates using Localdate

Asked

Viewed 2,915 times

2

I need to make a comparison of dates as follows:

dat_envio_shopping + 2 dias úteis < [data hoje]

Until then I have done so:

boletoSerasa.getEnvio().isBefore(LocalDate.now())

My question is in these "+2 working days".

How can I compare this "dat_envio_shopping + 2 business days"?

  • Define working days.

  • Monday to Friday.

2 answers

3


To add days to LocalDate, use the method plus(int, TemporalUnit).

To check if it is a working day, recommend that other answer of mine.

That way, to add up to two working days, you can do this:

public static boolean fimDeSemana(LocalDate ld) {
    DayOfWeek d = ld.getDayOfWeek();
    return d == DayOfWeek.SATURDAY || d == DayOfWeek.SUNDAY;
}

public static LocalDate mais2DiasUteis(LocalDate ld) {
    LocalDate novaData = ld.plus(2, ChronoUnit.DAYS);
    while (fimDeSemana(novaData)) {
        novaData = novaData.plus(1, ChronoUnit.DAYS);
    }
    return novaData;
}

To compare whether one date is earlier than another:

boolean antes = algumaData.isBefore(hoje);

Here’s a full test:

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.ResolverStyle;
import java.time.temporal.ChronoUnit;

class TesteData {
    public static boolean fimDeSemana(LocalDate ld) {
        DayOfWeek d = ld.getDayOfWeek();
        return d == DayOfWeek.SATURDAY || d == DayOfWeek.SUNDAY;
    }

    public static LocalDate mais2DiasUteis(LocalDate ld) {
        LocalDate novaData = ld.plus(2, ChronoUnit.DAYS);
        while (fimDeSemana(novaData)) {
            novaData = novaData.plus(1, ChronoUnit.DAYS);
        }
        return novaData;
    }

    public static void main(String[] args) {
        DateTimeFormatter fmt = DateTimeFormatter
                .ofPattern("dd/MM/uuuu")
                .withResolverStyle(ResolverStyle.STRICT);

        LocalDate algumaData1 = mais2DiasUteis(LocalDate.parse("04/09/2018", fmt));
        LocalDate hoje1 = LocalDate.parse("05/09/2018", fmt); //LocalDate.now();
        boolean antes1 = algumaData1.isBefore(hoje1);
        System.out.println(antes1 + " - " + fmt.format(algumaData1) + " - " + fmt.format(hoje1));

        LocalDate algumaData2 = mais2DiasUteis(LocalDate.parse("06/09/2018", fmt));
        LocalDate hoje2 = LocalDate.parse("10/09/2018", fmt); //LocalDate.now();
        boolean antes2 = algumaData2.isBefore(hoje2);
        System.out.println(antes2 + " - " + fmt.format(algumaData2) + " - " + fmt.format(hoje2));

        LocalDate algumaData3 = mais2DiasUteis(LocalDate.parse("06/09/2018", fmt));
        LocalDate hoje3 = LocalDate.parse("11/09/2018", fmt); //LocalDate.now();
        boolean antes3 = algumaData3.isBefore(hoje3);
        System.out.println(antes3 + " - " + fmt.format(algumaData3) + " - " + fmt.format(hoje3));
    }
}

That’s the way out:

false - 06/09/2018 - 05/09/2018
false - 10/09/2018 - 10/09/2018
true - 10/09/2018 - 11/09/2018

Note that the date of day 04/09 (Tuesday) It was played for 06/09 (Thursday). Already the date of 06/09 (Thursday) It was played for 10/09 (Monday), skipping the weekend.

See here working on ideone.

1

One option is to add 2 days, and if the result falls on a Saturday or Sunday, set the date for next Monday.

You can use the class java.time.temporal.TemporalAdjusters, who already owns a adjuster ready to return the next Monday:

LocalDate dataEnvio = ...
// somar dois dias
LocalDate doisDiasDepois = dataEnvio.plusDays(2);
// se caiu em um fim de semana (sábado ou domingo)
if (doisDiasDepois.getDayOfWeek() == DayOfWeek.SATURDAY
    || doisDiasDepois.getDayOfWeek() == DayOfWeek.SUNDAY) {
    // ajustar para a próxima segunda-feira
    doisDiasDepois = doisDiasDepois.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
}

if (doisDiasDepois.isBefore(LocalDate.now())) {
    ...
}

If you want, you can use import static to make the code a little more readable:

import static java.time.temporal.TemporalAdjusters.next;
import static java.time.DayOfWeek.*;

// ....
// se caiu em um fim de semana
if (doisDiasDepois.getDayOfWeek() == SATURDAY
    || doisDiasDepois.getDayOfWeek() == SUNDAY) {
    // ajustar para a próxima segunda-feira
    doisDiasDepois = doisDiasDepois.with(next(MONDAY));
}

Another alternative is to implement your own TemporalAdjuster. The difference is that this works with the interface java.time.temporal.Temporal (instead of working with a specific type, such as LocalDate).

The logic is the same (add 2 days, if fall in weekend, adjusts for the next Monday), but as Temporal does not have the methods plusDays and getDayOfWeek, the implementation is a little different:

public TemporalAdjuster somarDiasUteis(long dias) {
    return temporal -> {
        // somar a quantidade de dias
        temporal = temporal.plus(dias, ChronoUnit.DAYS);
        DayOfWeek dow = DayOfWeek.from(temporal);
        // se cai em fim de semana, ajusta para a próxima segunda
        if (dow == DayOfWeek.SATURDAY || dow == DayOfWeek.SUNDAY) {
            temporal = temporal.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
        }
        return temporal;
    };
}

To use, just pass the result to the method with:

LocalDate dataEnvio = ...
LocalDate doisDiasDepois = dataEnvio.with(somarDiasUteis(2));

The advantage is that this adjuster serves for any type that implements Temporal (i.e., all native types of the API, such as LocalDateTime, ZonedDateTime, etc), provided they have the date fields, of course (LocalTime, for example, there is no day, so it would not work with this class).

Browser other questions tagged

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