Hitung hari antara dua tanggal di Jawa 8


251

Saya tahu ada banyak pertanyaan di SO tentang cara mendapatkan, tapi saya ingin dan contoh menggunakan Java 8 Date api baru. Saya juga tahu perpustakaan JodaTime, tapi saya ingin cara kerja tanpa perpustakaan eksternal.

Fungsi perlu mengeluh dengan pembatasan ini:

  1. Mencegah kesalahan dari savelime tanggal
  2. Input adalah dua objek Date (tanpa waktu, saya tahu waktu lokal, tapi saya harus lakukan dengan instance date)

2
Sesuatu seperti ini misalnya ?
MadProgrammer

@ MadProgrammer Tidak juga - Durasi bukan yang paling cocok untuk melakukan itu ...
assylias

@assylias Ya, ini lebih baik daripada yang dimiliki OP
MadProgrammer

@assylias Lalu apa?
MadProgrammer

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

Jawaban:


435

Jika Anda ingin hari kalender logis , gunakan DAYS.between()metode dari java.time.temporal.ChronoUnit:

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

Jika Anda ingin 24 jam sehari , ( durasi ), Anda dapat menggunakan Durationkelas sebagai gantinya:

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

Untuk informasi lebih lanjut, lihat dokumen ini .


15
Itu melempar pengecualian, karena metode Duration.between membutuhkan objek temporal yang mampu mendukung unit DETIK . Sebagai gantinya, cobalah Duration.between(today.atTime(0, 0), yesterday.atTime(0, 0)).toDays().
VGR

5
Alih-alih today.atTime(0, 0)bisa Anda lakukan today.atStartOfDay().
eee

5
@REACHUS Mungkin -1 agak kasar karena kode yang Anda ajukan berfungsi, tetapi Durasi dimaksudkan untuk mengukur "jumlah waktu berdasarkan waktu". Ada cara bawaan untuk mengukur beberapa hari yang tidak memerlukan konversi dari tanggal ke waktu.
assylias

Jawaban yang lebih baik untuk LocalDate adalah jawaban @Sunil B di bawah ini:ChronoUnit.DAYS.between(firstDate, secondDate)
Lappro

@Appro mengapa lebih baik? Ia menggunakan metode yang sama dengan jawaban saya
syntagma

130

Berdasarkan komentar VGR di sini adalah apa yang dapat Anda gunakan:

ChronoUnit.DAYS.between(firstDate, secondDate)

38

Anda bisa menggunakan 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 yang baru saja saya temui dengan versi pertama untiladalah bahwa ia mengembalikan objek Periode . Itu akan mengembalikan beberapa tahun / bulan / hari antara dua tanggal, bukan jumlah hari yang sebenarnya. Dan getDays () pada Periode hanya mengembalikan bagian hari (tidak memperhitungkan jumlah tahun atau bulan), daripada jumlah total hari. Versi kedua berfungsi persis seperti yang diinginkan untuk mendapatkan jumlah hari antara dua tanggal.
M. Justin

Apakah ada alternatif lengkap untuk ini? Karena itu membutuhkan Android SDk 26 ke atas
ralphgabb

12

Anda dapat menggunakan DAYS.betweendarijava.time.temporal.ChronoUnit

misalnya

import java.time.temporal.ChronoUnit;

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

10

Jika startDate dan endDate adalah instance dari java.util.Date

Kita dapat menggunakan metode between () dari ChronoUnit enum:

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

ChronoUnit.DAYS menghitung hari yang diselesaikan 24 jam .

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

Gunakan DAYS di enum java.time.temporal.ChronoUnit . Di bawah ini adalah Kode Contoh:

Output: * Jumlah hari antara tanggal mulai: 2015-03-01 dan tanggal akhir: 2016-03-03 adalah ==> 368. ** Jumlah hari antara tanggal mulai: 2016-03-03 dan tanggal akhir: 2015-03-01 adalah ==> -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

Semua orang mengatakan untuk menggunakan ChronoUnit.DAYS.between tetapi itu hanya mendelegasikan ke metode lain yang bisa Anda sebut sendiri. Jadi bisa juga Anda lakukan firstDate.until(secondDate, ChronoUnit.DAYS).

Dokumen untuk keduanya sebenarnya menyebutkan kedua pendekatan dan mengatakan untuk menggunakan mana yang lebih mudah dibaca.


FWIW ... Saya tidak yakin mengapa keduanya ada. Apakah ada waktu yang satu lebih mudah dibaca dan waktu yang lain? Kapan / mengapa?
nafg

5

Ini dia:

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

Dapatkan beberapa hari sebelum Natal dari hari ini, coba ini

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

3

Jika tujuannya hanya untuk mendapatkan perbedaan dalam berhari-hari dan karena jawaban di atas menyebutkan tentang metode delegasi ingin menunjukkan bahwa dulu juga bisa menggunakan -

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

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

1
Pada musim gugur dalam perangkap untuk menggunakan 'Periode. Antara (date1, date2) .getDays ()' tanpa menyadari bahwa Anda kehilangan bulan dan tahun perbedaannya.
MrSmith42

2

dapatkan hari antara dua tanggal adalah turunan dari java.util.Date

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

1

Saya tahu pertanyaan ini untuk Java 8, tetapi dengan Java 9 Anda dapat menggunakan:

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

0

Gunakan kelas atau metode yang paling memenuhi kebutuhan Anda:

  • yang Durasi kelas,
  • Kelas periode ,
  • atau metode ChronoUnit.between .

A Durasi mengukur jumlah waktu menggunakan nilai-nilai berbasis waktu (detik, nanodetik).

Periode menggunakan nilai berbasis tanggal (tahun, bulan, hari).

Metode ChronoUnit.between berguna ketika Anda ingin mengukur jumlah waktu dalam satu unit waktu saja, seperti hari atau detik.

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.