คำนวณวันระหว่างสองวันใน Java 8


251

ฉันรู้ว่ามีคำถามมากมายเกี่ยวกับวิธีการรับ แต่ฉันต้องการและตัวอย่างโดยใช้ Java 8 Date API ใหม่ ฉันรู้จักห้องสมุด JodaTime ด้วย แต่ฉันต้องการวิธีการทำงานที่ไม่มีห้องสมุดภายนอก

ฟังก์ชั่นต้องบ่นด้วยข้อ จำกัด เหล่านี้:

  1. ป้องกันข้อผิดพลาดจากการบันทึกวันที่
  2. อินพุตเป็นวัตถุสองวันที่ (โดยไม่มีเวลาฉันรู้ว่าในช่วงเวลาท้องถิ่น แต่ฉันต้องทำกับอินสแตนซ์วันที่)

2
สิ่งที่ต้องการเช่นนี้ ?
MadProgrammer

@ MadProgrammer ไม่จริง - ระยะเวลาไม่ใช่แบบที่ดีที่สุดที่จะทำ ...
assylias

@assylias ดีกว่าสิ่งที่ OP มี
MadProgrammer

@assylias จากนั้นคืออะไร?
MadProgrammer

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

คำตอบ:


435

หากคุณต้องการใช้วันตามปฏิทินแบบลอจิคัลให้ใช้DAYS.between()วิธีจากjava.time.temporal.ChronoUnit:

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

หากคุณต้องการตัวอักษร 24 ชั่วโมงวัน ( ระยะเวลา ) คุณสามารถใช้Durationชั้นเรียนแทน:

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

สำหรับข้อมูลเพิ่มเติมอ้างอิงเอกสารนี้


15
ที่พ่นข้อยกเว้นเพราะวิธี Duration.between ต้องใช้วัตถุชั่วคราวสามารถรองรับหน่วยวินาที Duration.between(today.atTime(0, 0), yesterday.atTime(0, 0)).toDays()แต่พยายาม
VGR

5
แทนที่จะtoday.atTime(0, 0)ทำtoday.atStartOfDay()อย่างนั้น
eee

5
@REACHUS อาจ -1 เป็นบิตที่รุนแรงเพราะรหัสที่คุณเสนอให้ทำงาน แต่ระยะเวลานั้นหมายถึงการวัด มีวิธีการวัดจำนวนวันที่ไม่ต้องแปลงจากวันที่เป็นวันที่และเวลา
assylias

คำตอบที่ดีกว่าสำหรับ LocalDate คือ @Sunil B ด้านล่าง:ChronoUnit.DAYS.between(firstDate, secondDate)
Lappro

@ Lappro ทำไมมันดีกว่า มันใช้วิธีเดียวกันกับคำตอบของฉัน
syntagma

130

จากความคิดเห็นของ VGR นี่คือสิ่งที่คุณสามารถใช้ได้:

ChronoUnit.DAYS.between(firstDate, secondDate)

38

คุณสามารถใช้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 ที่ฉันเพิ่งพบกับเวอร์ชั่นแรกuntilคือมันคืนค่าอ็อบเจกต์Period นั่นจะส่งคืนจำนวนปี / เดือน / วันระหว่างวันที่สองวันไม่ใช่จำนวนวันจริง และ getDays () ในช่วงเวลาจะส่งกลับเฉพาะส่วนวันเท่านั้น (โดยไม่คำนึงถึงจำนวนปีหรือเดือน) แทนที่จะเป็นจำนวนวันทั้งหมด รุ่นที่สองทำงานตามที่ต้องการเพื่อให้ได้จำนวนวันระหว่างสองวัน
M. Justin

มีทางเลือกที่สมบูรณ์แบบสำหรับสิ่งนี้หรือไม่? เนื่องจากมันต้องการ Android SDk 26 ขึ้นไป
ralphgabb

12

คุณสามารถใช้DAYS.betweenจากjava.time.temporal.ChronoUnit

เช่น

import java.time.temporal.ChronoUnit;

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

10

หากstartDateและendDateเป็นอินสแตนซ์ของjava.util.Date

เราสามารถใช้วิธี()จากChronoUnit enum:

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

ChronoUnit.DAYSนับวันซึ่งเสร็จสิ้นภายใน 24 ชั่วโมง

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

ใช้วันใน enum java.time.temporal.ChronoUnit ด้านล่างเป็นรหัสตัวอย่าง:

เอาท์พุท: * จำนวนวันระหว่างวันที่เริ่มต้น: 2015-03-01 และวันที่สิ้นสุด: 2016-03-03 คือ ==> 368. ** จำนวนวันระหว่างวันที่เริ่มต้น: 2016-03-03 และวันที่สิ้นสุด: 2015-03-01 คือ ==> -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

ทุกคนกำลังบอกว่าจะใช้ ChronoUnit วันนี้ แต่ระหว่างนั้นเพียงมอบหมายให้วิธีการอื่นที่คุณสามารถเรียกตัวเองว่า ดังนั้นคุณสามารถทำได้firstDate.until(secondDate, ChronoUnit.DAYS)ดังนั้นคุณยังสามารถทำ

เอกสารสำหรับทั้งสองพูดถึงวิธีการทั้งสองและพูดว่าจะใช้วิธีใดที่อ่านได้มากกว่า


FWIW ... ฉันไม่แน่ใจว่าทำไมทั้งสองมีอยู่ มีบางครั้งที่หนึ่งสามารถอ่านได้มากขึ้นและเวลาที่อื่น ๆ คือ? เมื่อ / ทำไม?
nafg

5

ไปเลย:

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

รับจำนวนวันก่อนวันคริสต์มาสจากวันปัจจุบันลองนี้

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

3

หากเป้าหมายเพียงเพื่อให้ได้ความแตกต่างในวันและตั้งแต่คำตอบข้างต้นพูดถึงเกี่ยวกับวิธีการมอบหมายต้องการที่จะชี้ให้เห็นว่าครั้งเดียวก็สามารถใช้ -

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

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

1
อยู่ในกับดักให้ใช้ 'Period.between (date1, date2) .getDays ()' โดยไม่ทราบว่าคุณหลวมเดือนและปีของความแตกต่าง
MrSmith42

2

รับวันระหว่างสองวันที่วันที่เป็นตัวอย่างของ java.util.Date

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

1

ฉันรู้ว่าคำถามนี้สำหรับ Java 8 แต่ด้วย Java 9 คุณสามารถใช้:

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

0

ใช้คลาสหรือวิธีการที่ตรงกับความต้องการของคุณมากที่สุด:

  • ระยะเวลาเรียน
  • ชั้นเรียนระยะเวลา
  • หรือChronoUnit.b ระหว่างวิธี

ระยะเวลาวัดระยะเวลาโดยใช้ค่าตามเวลา (วินาที, นาโนวินาที)

งวดใช้ค่าตามวันที่ (ปี, เดือน, วัน)

กระบวนการ ChronoUnit.between มีประโยชน์เมื่อคุณต้องการวัดจำนวนเวลาในหน่วยเวลาเดียวเท่านั้นเช่นวันหรือวินาที

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.