Java 8 calculer les mois entre deux dates


REMARQUE CE N'EST PAS UN DUPLICATA DE L'UN DES

  • Calcul de la différence entre deux instances de date Java 43 réponses
  • calculer mois entre deux dates en java [dupliquer] 2 réponses

J'ai deux dates:

  • Date de début: "2016-08-31"
  • Date de fin: "2016-11-30"

Sa durée de 91 jours entre les deux dates ci-dessus, je m'attendais à ce que mon code renvoie une durée de 3 mois, mais les méthodes ci-dessous uniquement retourné 2 mois. Quelqu'un a une meilleure suggestion? Ou pensez-vous que c'est un bug dans Java 8? 91 jours la durée ne retourne que 2 mois.

Merci beaucoup pour l'aide.

Méthode 1:

Period diff = Period.between(LocalDate.parse("2016-08-31"),
    LocalDate.parse("2016-11-30"));

Méthode 2:

long daysBetween = ChronoUnit.MONTHS.between(LocalDate.parse("2016-08-31"),
    LocalDate.parse("2016-11-30"));

Méthode 3:

J'ai essayé d'utiliser la bibliothèque Joda au lieu des API Java 8, cela fonctionne. il loos retournera 3, Il semble que le calcul de la durée Java mois a également utilisé la valeur des jours. Mais dans mon cas, je ne peux pas utiliser le Joda dans mon projet. Donc, encore à la recherche d'autres solutions.

    LocalDate dateBefore= LocalDate.parse("2016-08-31");
    LocalDate dateAfter = LocalDate.parse("2016-11-30");
    int months = Months.monthsBetween(dateBefore, dateAfter).getMonths();
    System.out.println(months);
Author: SharpLu, 2018-02-23

4 answers

Puisque vous ne vous souciez pas des jours dans votre cas. Vous ne voulez que le nombre de mois entre deux dates, utilisez la documentation de la période pour adapter les dates, il a utilisé les jours comme expliqué par Jacob. Définissez simplement les jours des deux instances sur la même valeur (le premier jour du mois)

Period diff = Period.between(
            LocalDate.parse("2016-08-31").withDayOfMonth(1),
            LocalDate.parse("2016-11-30").withDayOfMonth(1));
System.out.println(diff); //P3M

Idem avec l'autre solution:

long daysBetween = ChronoUnit.MONTHS.between(
        LocalDate.parse("2016-08-31").withDayOfMonth(1),
        LocalDate.parse("2016-11-30").withDayOfMonth(1));
System.out.println(daysBetween); //3
 5
Author: AxelH, 2018-02-23 15:46:36

La documentation de Période # entre indique ce qui suit:

La date de début est incluse, mais pas la date de fin.

En outre:

Un mois est considéré si le jour de fin du mois est supérieur ou égal au jour de début du mois.

Votre jour de fin de mois 30 est pas supérieur ou égal à votre premier jour du mois 31, donc un troisième mois n'est pas considérée.

Notez le paramètre noms:

public static Period between​(LocalDate startDateInclusive, LocalDate endDateExclusive)

Pour retourner 3 mois, vous pouvez incrémenter le endDateExclusive d'un seul jour.

 3
Author: Jacob G., 2018-02-23 15:21:23

Au cas où vous voudriez vous en tenir à java.time.Period API

Selon java.time.Period documentation

Period between(LocalDate startDateInclusive, LocalDate endDateExclusive)

@param startDateInclusive  the start date, inclusive, not null
@param endDateExclusive  the end date, exclusive, not null

Il est donc préférable d'ajuster votre implémentation pour inclure votre date de fin et obtenir le résultat souhaité

Period diff = Period.between(LocalDate.parse("2016-08-31"),
                LocalDate.parse("2016-11-30").plusDays(1));
System.out.println("Months : " + diff.getMonths());
//Output -> Months : 3
 1
Author: abhi, 2018-09-12 17:04:36

Après la courte enquête, je n'ai toujours pas totalement résolu ma question, Mais j'ai utilisé une solution sale pour éviter de renvoyer la durée incorrecte. Au moins, nous pouvons obtenir les mois de durée raisonnable.

private static long durationMonths(LocalDate dateBefore, LocalDate dateAfter) {
        System.out.println(dateBefore+"   "+dateAfter);
        if (dateBefore.getDayOfMonth() > 28) {
            dateBefore = dateBefore.minusDays(5);
        } else if (dateAfter.getDayOfMonth() > 28) {
            dateAfter = dateAfter.minusDays(5);
        }
        return ChronoUnit.MONTHS.between(dateBefore, dateAfter);
    }
 0
Author: SharpLu, 2018-02-23 15:47:20