Calculer les jours entre deux dates dans Java 8

251

Je sais qu'il y a beaucoup de questions sur SO sur la façon d'obtenir, mais je veux et par exemple utiliser la nouvelle API Java 8 Date. Je connais également la bibliothèque JodaTime, mais je veux une méthode de travail sans bibliothèques externes.

La fonction doit se plaindre de ces restrictions:

  1. Empêche les erreurs de sauvegarder la date
  2. Les entrées sont deux objets de Date (sans heure, je connais localdatetime, mais je dois faire avec les instances de date)
Marcos
la source
2
Quelque chose comme ça par exemple ?
MadProgrammer
@MadProgrammer Pas vraiment - La durée n'est pas la meilleure
option
@assylias Eh bien, c'est mieux que ce que le PO avait
MadProgrammer
@assylias Alors qu'est-ce que c'est?
MadProgrammer
16
@MadProgrammer DAYS.between(localDate1, localDate2).
assylias

Réponses:

435

Si vous voulez des jours calendaires logiques , utilisez la DAYS.between()méthode de java.time.temporal.ChronoUnit:

LocalDate dateBefore;
LocalDate dateAfter;
long daysBetween = DAYS.between(dateBefore, dateAfter);

Si vous voulez des jours littéraux de 24 heures (une durée ), vous pouvez utiliser la Durationclasse à la place:

LocalDate today = LocalDate.now()
LocalDate yesterday = today.minusDays(1);
// Duration oneDay = Duration.between(today, yesterday); // throws an exception
Duration.between(today.atStartOfDay(), yesterday.atStartOfDay()).toDays() // another option

Pour plus d'informations, reportez-vous à ce document .

syntagme
la source
15
Cela lève une exception, car la méthode Duration.between nécessite des objets temporels capables de prendre en charge l'unité SECONDS . Essayez plutôt Duration.between(today.atTime(0, 0), yesterday.atTime(0, 0)).toDays().
VGR
5
Au lieu de today.atTime(0, 0)vous pouvez le faire today.atStartOfDay().
eee
5
@REACHUS Peut-être que le -1 était un peu dur parce que le code que vous proposez fonctionne, mais la durée est censée mesurer "les quantités de temps basées sur le temps". Il existe un moyen intégré de mesurer un nombre de jours qui ne nécessite pas de conversion de la date en datetime.
assylias
La meilleure réponse pour LocalDate est la réponse de @Sunil B ci-dessous:ChronoUnit.DAYS.between(firstDate, secondDate)
Lappro
@Lappro pourquoi est-ce mieux? Il utilise la même méthode que ma réponse
syntagma
130

Sur la base des commentaires de VGR, voici ce que vous pouvez utiliser:

ChronoUnit.DAYS.between(firstDate, secondDate)
Sunil B
la source
38

Vous pouvez utiliser until():

LocalDate independenceDay = LocalDate.of(2014, Month.JULY, 4);
LocalDate christmas = LocalDate.of(2014, Month.DECEMBER, 25);

System.out.println("Until christmas: " + independenceDay.until(christmas));
System.out.println("Until christmas (with crono): " + independenceDay.until(christmas, ChronoUnit.DAYS));
nazar_art
la source
4
Le problème que je viens de rencontrer avec la première version untilest qu'il renvoie un objet Period . Cela renverra un certain nombre d'années / mois / jours entre les deux dates, pas le nombre réel de jours. Et getDays () sur la période ne renvoie que la partie jours (sans tenir compte du nombre d'années ou de mois), plutôt que le nombre total de jours. La deuxième version fonctionne exactement comme vous le souhaitez pour obtenir un nombre de jours entre deux dates.
M. Justin
Y a-t-il une alternative complète pour cela pour cela? Puisqu'il a besoin d'Android SDk 26 et supérieur
ralphgabb
12

Vous pouvez utiliser à DAYS.betweenpartir dejava.time.temporal.ChronoUnit

par exemple

import java.time.temporal.ChronoUnit;

public long getDaysCountBetweenDates(LocalDate dateBefore, LocalDate dateAfter) {
    return DAYS.between(dateBefore, dateAfter);
}
Piotr Fryga
la source
10

Si startDate et endDate sont des instances de java.util.Date

Nous pouvons utiliser la méthode between () de l' énumération ChronoUnit :

public long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive) {
    //..
}

ChronoUnit.DAYS compte les jours qui se sont terminés sur 24 heures .

import java.time.temporal.ChronoUnit;

ChronoUnit.DAYS.between(startDate.toInstant(), endDate.toInstant());

//OR 

ChronoUnit.DAYS.between(Instant.ofEpochMilli(startDate.getTime()), Instant.ofEpochMilli(endDate.getTime()));
Pawan
la source
8

Utilisez les JOURS dans l'énumération java.time.temporal.ChronoUnit . Voici l'exemple de code:

Sortie: * Nombre de jours entre la date de début: 2015-03-01 et la date de fin: 2016-03-03 est ==> 368. ** Nombre de jours entre la date de début: 2016-03-03 et la date de fin: 2015-03-01 est ==> -368 *

package com.bitiknow.date;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

/**
 * 
 * @author pradeep
 *
 */
public class LocalDateTimeTry {
    public static void main(String[] args) {

        // Date in String format.
        String dateString = "2015-03-01";

        // Converting date to Java8 Local date
        LocalDate startDate = LocalDate.parse(dateString);
        LocalDate endtDate = LocalDate.now();
        // Range = End date - Start date
        Long range = ChronoUnit.DAYS.between(startDate, endtDate);
        System.out.println("Number of days between the start date : " + dateString + " and end date : " + endtDate
                + " is  ==> " + range);

        range = ChronoUnit.DAYS.between(endtDate, startDate);
        System.out.println("Number of days between the start date : " + endtDate + " and end date : " + dateString
                + " is  ==> " + range);

    }

}
Pradeep Padmarajaiah
la source
8

Tout le monde dit d'utiliser ChronoUnit.DAYS.between mais cela délègue simplement à une autre méthode que vous pourriez vous appeler. Vous pourriez donc aussi le faire firstDate.until(secondDate, ChronoUnit.DAYS).

Les documents pour les deux mentionnent en fait les deux approches et disent d'utiliser celle qui est plus lisible.

nafg
la source
FWIW ... Je ne sais pas pourquoi les deux existent. Y a-t-il des moments où l'un est plus lisible et des moments où l'autre l'est? Quand Pourquoi?
nafg
5

Voici:

public class DemoDate {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        System.out.println("Current date: " + today);

        //add 1 month to the current date
        LocalDate date2 = today.plus(1, ChronoUnit.MONTHS);
        System.out.println("Next month: " + date2);

        // Put latest date 1st and old date 2nd in 'between' method to get -ve date difference
        long daysNegative = ChronoUnit.DAYS.between(date2, today);
        System.out.println("Days : "+daysNegative);

        // Put old date 1st and new date 2nd in 'between' method to get +ve date difference
        long datePositive = ChronoUnit.DAYS.between(today, date2);
        System.out.println("Days : "+datePositive);
    }
}
Pra_A
la source
5

Obtenez le nombre de jours avant Noël à partir du jour actuel, essayez ceci

System.out.println(ChronoUnit.DAYS.between(LocalDate.now(),LocalDate.of(Year.now().getValue(), Month.DECEMBER, 25)));
survivant_27
la source
3

Si l'objectif est simplement d'obtenir la différence en jours et que les réponses ci-dessus mentionnent les méthodes de délégué, je voudrais souligner qu'une fois, vous pouvez également simplement utiliser -

public long daysInBetween(java.time.LocalDate startDate, java.time.LocalDate endDate) {
  // Check for null values here

  return endDate.toEpochDay() - startDate.toEpochDay();
}
levenshtein
la source
1
À l'automne dans le piège d'utiliser 'Period.between (date1, date2) .getDays ()' sans se rendre compte que vous perdez les mois et les années de la différence.
MrSmith42
2

obtenir des jours entre deux dates date est une instance de java.util.Date

public static long daysBetweenTwoDates(Date dateFrom, Date dateTo) {
            return DAYS.between(Instant.ofEpochMilli(dateFrom.getTime()), Instant.ofEpochMilli(dateTo.getTime()));
        }
Mohamed.Abdo
la source
1

Je sais que cette question concerne Java 8, mais avec Java 9, vous pouvez utiliser:

public static List<LocalDate> getDatesBetween(LocalDate startDate, LocalDate endDate) {
    return startDate.datesUntil(endDate)
      .collect(Collectors.toList());
}
Xxtreem
la source
0

Utilisez la classe ou la méthode qui répond le mieux à vos besoins:

  • la classe Durée ,
  • Classe de période ,
  • ou la méthode ChronoUnit.between .

Une durée mesure une durée en utilisant des valeurs basées sur le temps (secondes, nanosecondes).

Une période utilise des valeurs basées sur la date (années, mois, jours).

La méthode ChronoUnit.between est utile lorsque vous souhaitez mesurer une quantité de temps dans une seule unité de temps, comme des jours ou des secondes.

https://docs.oracle.com/javase/tutorial/datetime/iso/period.html

Samuel
la source