Oblicz dni między dwiema datami w Javie 8


251

Wiem, że jest wiele pytań na temat SO, ale chcę i przykład przy użyciu nowego interfejsu API Java 8 Date. Znam również bibliotekę JodaTime, ale chcę sposób pracy bez bibliotek zewnętrznych.

Funkcja musi narzekać na te ograniczenia:

  1. Zapobiegaj błędom od daty oszczędzania
  2. Dane wejściowe to dwa obiekty Data (bez czasu znam lokalny czas, ale muszę zrobić z instancjami daty)

2
Coś takiego na przykład ?
— MadProgrammer,

@MadProgrammer Niezupełnie - Czas trwania nie jest najlepszy, aby to zrobić ...
— assylias,

@assylias Cóż, to lepsze niż OP
— MadProgrammer,

@assylias Więc co to jest?
— MadProgrammer,

16
@MadProgrammer DAYS.between(localDate1, localDate2).
— assylias,

Odpowiedzi:


435

Jeśli chcesz logiczne dni kalendarzowe , użyj DAYS.between()metody z java.time.temporal.ChronoUnit:

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

Jeśli chcesz dosłownie 24 godziny na dobę ( czas trwania ), możesz Durationzamiast tego skorzystać z zajęć:

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

Aby uzyskać więcej informacji, zapoznaj się z tym dokumentem .


15
Zgłasza to wyjątek, ponieważ metoda Duration.between wymaga obiektów czasowych zdolnych do obsługi jednostki SECONDS . Zamiast tego spróbuj Duration.between(today.atTime(0, 0), yesterday.atTime(0, 0)).toDays().
— VGR

5
Zamiast today.atTime(0, 0)ciebie możesz to zrobić today.atStartOfDay().
— eee

5
@ REACHUS Być może -1 był nieco trudny, ponieważ proponowany przez ciebie kod działa, ale czas trwania ma mierzyć „ilość czasu zależną od czasu”. Istnieje wbudowany sposób pomiaru liczby dni, który nie wymaga konwersji z daty na datę i godzinę.
— assylias,

Lepszą odpowiedzią na LocalDate jest odpowiedź @Sunila B poniżej:ChronoUnit.DAYS.between(firstDate, secondDate)
— Lappro

@Lappro dlaczego jest lepiej? Używa tej samej metody, co moja odpowiedź
— syntagma

130

Na podstawie komentarzy VGR tutaj możesz użyć:

ChronoUnit.DAYS.between(firstDate, secondDate)

38

Możesz użyć 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));

4
Gotcha, którą właśnie spotkałem w pierwszej wersji, untilpolega na tym, że zwraca obiekt okresu . To zwróci liczbę lat / miesięcy / dni między dwiema datami, a nie faktyczną liczbę dni. A getDays () w okresie zwraca tylko część dni (nie biorąc pod uwagę liczby lat lub miesięcy), a nie całkowitą liczbę dni. Druga wersja działa dokładnie tak, jak trzeba, aby uzyskać liczbę dni między dwiema datami.
— M. Justin,

Czy jest na to pełna alternatywa? Ponieważ wymaga Androida SDk 26 i nowszych
— ralphgabb

12

Możesz używać DAYS.betweenzjava.time.temporal.ChronoUnit

na przykład

import java.time.temporal.ChronoUnit;

public long getDaysCountBetweenDates(LocalDate dateBefore, LocalDate dateAfter) {
    return DAYS.between(dateBefore, dateAfter);
}

10

Jeśli startDate i endDate są instancją java.util.Date

Możemy użyć metody between () z ChronoUnit enum:

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

ChronoUnit.DAYS zlicza dni, które ukończyły 24 godziny .

import java.time.temporal.ChronoUnit;

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

//OR 

ChronoUnit.DAYS.between(Instant.ofEpochMilli(startDate.getTime()), Instant.ofEpochMilli(endDate.getTime()));

8

Użyj DAYS in enum java.time.temporal.ChronoUnit . Poniżej znajduje się przykładowy kod:

Dane wyjściowe: * Liczba dni między datą rozpoczęcia: 01.03.2015 a datą zakończenia: 2016-03-03 wynosi ==> 368. ** Liczba dni między datą rozpoczęcia: 03.03.2016 i datą zakończenia: 01.03.2015 jest ==> -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);

    }

}

8

Wszyscy mówią, aby używać ChronoUnit.DAYS.between, ale to tylko deleguje na inną metodę, którą możesz nazwać sobą. Więc możesz też zrobić firstDate.until(secondDate, ChronoUnit.DAYS).

Dokumenty dla obu faktycznie wspominają o obu podejściach i mówią, aby użyć tego, który jest bardziej czytelny.


FWIW ... Nie jestem pewien, dlaczego oba istnieją. Czy są chwile, kiedy jeden jest bardziej czytelny, a czasami drugi? Kiedy, dlaczego?
— nafg

5

Proszę bardzo:

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);
    }
}

5

Uzyskaj liczbę dni przed świętami Bożego Narodzenia od bieżącego dnia, spróbuj tego

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

3

Jeśli celem jest uzyskanie różnicy w dniach, a ponieważ powyższe odpowiedzi wspominają o metodach delegowania, chcielibyśmy zauważyć, że kiedyś można po prostu użyć -

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

  return endDate.toEpochDay() - startDate.toEpochDay();
}

1
Jesienią wpadnie w pułapkę, aby użyć „Period.between (date1, date2) .getDays ()”, nie zdając sobie sprawy, że tracisz miesiące i lata różnicy.
— MrSmith42

2

get dni między dwiema datami data jest instancją java.util.Date

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

1

Wiem, że to pytanie dotyczy Java 8, ale w Javie 9 możesz użyć:

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

0

Użyj klasy lub metody, która najlepiej odpowiada Twoim potrzebom:

  • klasa czasu trwania ,
  • Klasa okresowa ,
  • lub metoda ChronoUnit.between .

Czas trwania mierzy czas przy użyciu wartości opartych na czasie (sekundy, nanosekundy).

Okres używa wartości opartych na dacie (lata, miesiące, dni).

Metoda ChronoUnit.between jest przydatna, gdy chcesz zmierzyć ilość czasu w pojedynczej jednostce czasu, na przykład dni lub sekund.

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.