Tính ngày giữa hai ngày trong Java 8


250

Tôi biết có rất nhiều câu hỏi về SO về cách lấy, nhưng tôi muốn và ví dụ sử dụng api Java 8 ngày mới. Tôi cũng biết thư viện JodaTime, nhưng tôi muốn một cách làm việc mà không có thư viện bên ngoài.

Chức năng cần khiếu nại với những hạn chế sau:

  1. Ngăn chặn lỗi từ ngày cứu tinh
  2. Đầu vào là hai đối tượng của Ngày (không có thời gian, tôi biết thời gian địa phương, nhưng tôi cần thực hiện với các trường hợp ngày)

2
Một cái gì đó như thế này chẳng hạn ?
MadProgrammer

@MadProgrammer Không thực sự - Thời lượng không phù hợp nhất để làm điều đó ...
assylias

@assylias Chà, nó tốt hơn những gì OP có
MadProgrammer

@assylias Vậy thì sao?
MadProgrammer

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

Câu trả lời:


434

Nếu bạn muốn ngày dương lịch , sử dụng DAYS.between()phương pháp từ java.time.temporal.ChronoUnit:

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

Nếu bạn muốn theo nghĩa đen 24 ngày , ( thời lượng ), bạn có thể sử dụng Durationlớp thay thế:

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

Để biết thêm thông tin, tham khảo tài liệu này .


15
Điều đó đưa ra một ngoại lệ, bởi vì phương thức terms.b between yêu cầu các đối tượng tạm thời có khả năng hỗ trợ đơn vị SECONDS . Thay vào đó, hãy thử Duration.between(today.atTime(0, 0), yesterday.atTime(0, 0)).toDays().
VGR

5
Thay vì today.atTime(0, 0)bạn có thể làm today.atStartOfDay().
eee

5
@REACHUS Có thể -1 hơi khó khăn vì mã bạn đề xuất hoạt động, nhưng Thời lượng có nghĩa là để đo "lượng thời gian dựa trên thời gian". Có một cách tích hợp để đo một số ngày không yêu cầu chuyển đổi từ ngày này sang ngày khác.
assylias

Câu trả lời tốt hơn cho LocalDate's là câu trả lời của @Sunil B bên dưới:ChronoUnit.DAYS.between(firstDate, secondDate)
Lappro

@Lappro tại sao nó tốt hơn? Nó sử dụng phương pháp tương tự như câu trả lời của tôi
cú pháp

130

Dựa trên ý kiến ​​của VGR ở đây là những gì bạn có thể sử dụng:

ChronoUnit.DAYS.between(firstDate, secondDate)

38

Bạn có thể sử dụng 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 tôi chỉ gặp phải với phiên bản đầu tiên của untillà nó trả về một thời kỳ đối tượng. Điều đó sẽ trả về một số năm / tháng / ngày giữa hai ngày, không phải số ngày thực tế. Và getDays () trên Thời gian chỉ trả về phần ngày (không tính đến số năm hoặc tháng), thay vì tổng số ngày. Phiên bản thứ hai hoạt động chính xác như mong muốn để có được một số ngày giữa hai ngày.
M. Justin

Có một sự thay thế hoàn toàn cho việc này không? Vì nó cần Android SDk 26 trở lên
ralphgabb

12

Bạn có thể sử dụng DAYS.betweentừjava.time.temporal.ChronoUnit

ví dụ

import java.time.temporal.ChronoUnit;

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

10

Nếu startDateendDate là ví dụ của java.util.Date

Chúng ta có thể sử dụng phương thức between () từ ChronoUnit enum:

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

ChronoUnit.DAYS đếm số ngày hoàn thành trong 24 giờ .

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

Sử dụng NGÀY trong enum java.time.temporal.ChronoUnit . Dưới đây là Mã mẫu:

Đầu ra: * Số ngày giữa ngày bắt đầu: 2015-03-01 và ngày kết thúc: 2016/03/03 là ==> 368. ** Số ngày giữa ngày bắt đầu: 2016-03-03 và ngày kết thúc: 2015 / 03-01 là ==> -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

Mọi người đều nói sử dụng ChronoUnit.DAYS.b between nhưng chỉ cần ủy quyền cho một phương thức khác mà bạn có thể tự gọi cho mình. Vì vậy, bạn cũng có thể làm firstDate.until(secondDate, ChronoUnit.DAYS).

Các tài liệu cho cả hai thực sự đề cập đến cả hai cách tiếp cận và nói sử dụng cái nào dễ đọc hơn.


FWIW ... Tôi không chắc tại sao cả hai tồn tại. Có những lúc người này dễ đọc hơn và lần kia là lần khác? Khi nao tại sao?
nafg

5

Ở đây bạn đi:

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

Nhận số ngày trước Giáng sinh từ ngày hiện tại, hãy thử điều này

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

3

Nếu mục tiêu chỉ là để có được sự khác biệt theo ngày và vì các câu trả lời ở trên đề cập đến các phương thức đại biểu muốn chỉ ra rằng một lần cũng có thể sử dụng một cách đơn giản -

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

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

1
Khi rơi vào bẫy để sử dụng 'period.b between (date1, date2) .getDays ()' mà không nhận ra rằng bạn mất các tháng và năm chênh lệch.
MrSmith42

2

nhận được ngày giữa hai ngày ngày là ví dụ của java.util.Date

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

1

Tôi biết câu hỏi này dành cho Java 8, nhưng với Java 9 bạn có thể sử dụng:

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

0

Sử dụng lớp hoặc phương thức đáp ứng tốt nhất nhu cầu của bạn:

  • các Thời gian lớp học,
  • Lớp học thời gian ,
  • hoặc phương thức ChronoUnit.b between .

Thời lượng đo một lượng thời gian bằng cách sử dụng các giá trị dựa trên thời gian (giây, nano giây).

Một khoảng thời gian sử dụng các giá trị dựa trên ngày (năm, tháng, ngày).

Phương thức ChronoUnit.b between rất hữu ích khi bạn muốn đo một lượng thời gian chỉ trong một đơn vị thời gian, chẳng hạn như ngày hoặc giây.

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.