Compare dates using LocalDate

2

I need to do a date comparison as follows:

dat_envio_shopping + 2 dias úteis < [data hoje]

Until then I have done so:

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

My question stays in these "+2 business days".

How can I make this comparison of "dat_envio_shopping + 2 business days"?

    
asked by anonymous 05.09.2018 / 20:35

2 answers

3

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

To check if it's a working day, I recommend this other answer of mine .

So, to add two 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 if one date is earlier than another:

boolean antes = algumaData.isBefore(hoje);

Here's a complete 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));
    }
}

The output is this:

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

Please note that the date of 04/09 (Tuesday) was moved to 06/09 (Thursday). Already the date of 06/09 (Thursday) was played to 10/09 (Monday), skipping the weekend.

See here working on ideone.

    
05.09.2018 / 20:56
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 , which already has an adjuster ready to return to the next second:

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 bit 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 it 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 it falls on the weekend, it adjusts for the next second), but since Temporal does not have the plusDays and getDayOfWeek methods, the implementation is slightly 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 with method:

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

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

    
05.09.2018 / 20:46