Java 8で2つの日付間の日数を計算する


250

取得する方法についてSOに多くの質問があることを知っていますが、新しいJava 8 Date APIを使用して例を求めています。JodaTimeライブラリも知っていますが、外部ライブラリを使用せずに作業できる方法を求めています。

関数は次の制限に準拠する必要があります。

  1. 日付の保存時間によるエラーを防止
  2. 入力は2つのDateオブジェクトです(時間なし、localdatetimeは知っていますが、日付インスタンスを使用する必要があります)。

2
たとえばこのような何か?
MadProgrammer 2014年

@MadProgrammer本当にそうではない-期間はそれを行うのに最適ではない...
assylias '19 / 11/14

@assyliasまあ、それはOPが持っていたものより優れています
MadProgrammer '19 / 11/14

@assyliasそれでは何ですか?
MadProgrammer 2014年

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

回答:


434

論理的な暦日が必要場合は、次の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メソッドはSECONDSユニットをサポートできる一時オブジェクトを必要とするため、これ例外をスローします。代わりに、を試してくださいDuration.between(today.atTime(0, 0), yesterday.atTime(0, 0)).toDays()
VGR 2014年

5
代わりにtoday.atTime(0, 0)できますtoday.atStartOfDay()
eee 2014年

5
@REACHUS提案したコードが機能するため、-1は少し厳しいかもしれませんが、Durationは「時間ベースの時間」を測定することを目的としています。日付から日時への変換を必要としない、日数を測定する組み込みの方法があります。
assylias 2014年

:LOCALDATEのためのより良い答えは以下@Sunil Bの答えであるChronoUnit.DAYS.between(firstDate, secondDate)
Lappro

@Lapproなぜそれが良いのですか?それは私の答えと同じ方法を使用します
シンタグマ

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
の最初のバージョンでちょうど遭遇した落とし穴untilは、Periodオブジェクトを返すことです。これは、実際の日数ではなく、2つの日付間の年数/月数/日数を返します。また、PeriodのgetDays()は、日数の合計ではなく、日数のみを返します(年または月の数は考慮しません)。2番目のバージョンは、2つの日付間の日数を取得するために、希望どおりに機能します。
M.ジャスティン

このための完全な代替策はありますか?Android
SDk

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

場合たstartDateendDateにはのインスタンスですjava.util.Date

ChronoUnit enumのbetween()メソッドを使用できます。

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

列挙java.time.temporal.ChronoUnitのDAYSを使用します。以下はサンプルコードです:

出力: *開始日: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.DAYS.betweenを使用するように言っていますが、それはあなたが呼び出すことができる別のメソッドに委譲するだけです。したがって、あなたも行うことができますfirstDate.until(secondDate, ChronoUnit.DAYS)

両方のドキュメントは、実際には両方のアプローチに言及しており、どちらか読みやすい方を使用するように言っています。


FWIW ...両方が存在する理由がわかりません。一方がより読みやすい場合と、もう一方が読みやすい場合がありますか?いつ/なぜ?
nafg 2018年

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

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.betweenメソッド。

期間は、時間ベースの値(秒、ナノ秒)を使用して時間を測定します。

期間は日付ベースの値(年、月、日)を使用します。

ChronoUnit.betweenメソッドは、日や秒など、単一の時間単位のみで時間を測定する場合に便利です。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.