web-dev-qa-db-ja.com

Joda-Timeの2つの日付の間の日数

2つの--- Joda-TimeDateTime インスタンスの間の日数の違いを見つけるにはどうすればいいですか? 「日数の差」とは、開始日が月曜日で終了日が火曜日であれば、開始日と終了日の時、分、秒に関係なく、戻り値1が期待されるということです。

Days.daysBetween(start, end).getDays()は、開始が夕方、朝が終わると0を返します。

私は他の日付フィールドについても同じ問題を抱えているので、それほど重要ではないフィールドを「無視する」一般的な方法があることを望みました。

つまり、2月から3月4日の間の月も1になり、14:45から15:12の間の時間も1になります。しかし、14:01と14:55の時差は0になります。

313
pvgoddijn

厄介なことに、withTimeAtStartOfDayの回答は間違っていますが、時折起こります。あなたが欲しい:

Days.daysBetween(start.toLocalDate(), end.toLocalDate()).getDays()

それは "真夜中/一日の始まり"が時々1amを意味することが判明します(夏時間はこのようにいくつかの場所で起こる)、Days.daysBetweenは適切に処理しません。

// 5am on the 20th to 1pm on the 21st, October 2013, Brazil
DateTimeZone BRAZIL = DateTimeZone.forID("America/Sao_Paulo");
DateTime start = new DateTime(2013, 10, 20, 5, 0, 0, BRAZIL);
DateTime end = new DateTime(2013, 10, 21, 13, 0, 0, BRAZIL);
System.out.println(daysBetween(start.withTimeAtStartOfDay(),
                               end.withTimeAtStartOfDay()).getDays());
// prints 0
System.out.println(daysBetween(start.toLocalDate(),
                               end.toLocalDate()).getDays());
// prints 1

LocalDate経由で進むと、問題全体が回避されます。

370
Alice Purcell

Daysクラス

Days クラスを withTimeAtStartOfDay メソッドと共に使用するとうまくいくはずです。

Days.daysBetween(start.withTimeAtStartOfDay() , end.withTimeAtStartOfDay() ).getDays() 
183

LocalDate を使うことができます。

Days.daysBetween(new LocalDate(start), new LocalDate(end)).getDays() 
83
Bozho

tl; dr

Java.time.temporal.ChronoUnit.DAYS.between( 
    earlier.truncatedTo( ChronoUnit.DAYS )  , 
    later.truncatedTo( ChronoUnit.DAYS ) 
)

…または…

Java.time.temporal.ChronoUnit.HOURS.between( 
    earlier.truncatedTo( ChronoUnit.HOURS )  , 
    later.truncatedTo( ChronoUnit.HOURS ) 
)

Java.time

参考までに、 Joda-Time プロジェクトは メンテナンスモード になりました。チームは Java.time クラスへの移行を勧めています。

Joda-TimeのDateTimeと同等のものはZonedDateTimeです。

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;

どうやらあなたは日にちを日数で数えたい、つまりあなたはその日の時間を無視したいのです。たとえば、深夜0時の1分前から開始し、深夜0時の1分後に終了すると、1日になります。この動作のために、LocalDateからZonedDateTimeを抽出します。 LocalDate クラスは、時刻なし、タイムゾーンなしの日付のみの値を表します。

LocalDate localDateStart = zdtStart.toLocalDate() ;
LocalDate localDateStop = zdtStop.toLocalDate() ;

経過日数または他の単位を計算するには、 ChronoUnit 列挙型を使用します。

long days = ChronoUnit.DAYS.between( localDateStart , localDateStop ) ;

切り捨て

60分の時間としての完全な時間ではなく、時間のデルタを時間の単位として使用する場合に、このカウントを行うためのより一般的な方法について質問する場合は、truncatedToメソッドを使用してください。

これが同日の14時45分から15時12分の例です。

ZoneId z = ZoneId.of( "America/Montreal" ); 
ZonedDateTime start = ZonedDateTime.of( 2017 , 1 , 17 , 14 , 45 , 0 , 0 , z );
ZonedDateTime stop = ZonedDateTime.of( 2017 , 1 , 17 , 15 , 12 , 0 , 0 , z );

long hours = ChronoUnit.HOURS.between( start.truncatedTo( ChronoUnit.HOURS ) , stop.truncatedTo( ChronoUnit.HOURS ) );

1

日付による日数の場合は、ChronoUnit.DAYSに切り捨てます。これは、経過日数が1の5分前から5分後まで真夜中を過ぎる例です。

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime start = ZonedDateTime.of( 2017 , 1 , 17 , 23 , 55 , 0 , 0 , z );
ZonedDateTime stop = ZonedDateTime.of( 2017 , 1 , 18 , 00 , 05 , 0 , 0 , z );

long days = ChronoUnit.DAYS.between( start.truncatedTo( ChronoUnit.DAYS ) , stop.truncatedTo( ChronoUnit.DAYS ) );

1


Java.timeについて

Java.time フレームワークは、Java 8以降に組み込まれています。これらのクラスは、 Java.util.DateCalendar 、& SimpleDateFormat のような、面倒な古い レガシー 日時クラスに代わるものです。

Joda-Time プロジェクトは、現在 メンテナンスモード になっており、 Java.time クラスに移行するように勧めています。

詳細については、 Oracleチュートリアル を参照してください。そして多くの例と説明についてはStack Overflowを検索してください。指定は JSR 31 です。

データベースと直接Java.timeオブジェクトを交換することができます。 JDBC 4.2 以降に準拠した JDBCドライバー を使用してください。文字列もJava.sql.*クラスも必要ありません。

Java.timeクラスはどこで入手できますか?

  • Java SE 8Java SE 9Java SE 1 、およびそれ以降
    • ビルトイン。
    • バンドル実装の標準Java APIの一部。
    • Java 9はいくつかのマイナーな機能と修正を追加します。
  • Java SE 6 および Java SE 7
    • Java.timeの機能の多くは、 ThreeTen-Backport でJava 6と7にバックポートされています。
  • Android
    • Java.timeクラスのAndroidバンドル実装の最新バージョン。
    • 以前のAndroid(<26)では、 ThreeTenABP プロジェクトが適応ThreeTen-Backport(上記の通り)。 ThreeTenABPの使い方… を参照してください。

ThreeTen-Extra プロジェクトはJava.timeを追加のクラスで拡張します。このプロジェクトは、Java.timeに将来追加される可能性があることを証明するものです。 IntervalYearWeekYearQuartermore などの便利なクラスがあります。

ThreeTen-Extra プロジェクトはJava.timeを追加のクラスで拡張します。このプロジェクトは、Java.timeに将来追加される可能性があることを証明するものです。 IntervalYearWeekYearQuartermore などの便利なクラスがあります。

6
Basil Bourque

受け入れられた答えは2つのLocalDateオブジェクトを構築します、あなたがたくさんのデータを読んでいるならば、それらは非常に高価です。私はこれを使う:

  public static int getDaysBetween(DateTime earlier, DateTime later)
  {
    return (int) TimeUnit.MILLISECONDS.toDays(later.getMillis()- earlier.getMillis());
  }

getMillis()を呼び出すことによって、あなたはすでに存在する変数を使います。
MILLISECONDS.toDays()は、その後、単純な算術計算を使用し、オブジェクトを作成しません。

2
JBoy

Java.time.Period

Java.time.Period クラスを count days に使用します。

Java 8では、LocalDateを使用して差を計算する方がより直感的です。2つの日付を表すのにLocalDateTime

    LocalDate now = LocalDate.now();
    LocalDate inputDate = LocalDate.of(2018, 11, 28);

    Period period = Period.between( inputDate, now);
    int diff = period.getDays();
    System.out.println("diff = " + diff);
1
AzizSM
DateTime  dt  = new DateTime(laterDate);        

DateTime newDate = dt.minus( new  DateTime ( previousDate ).getMillis());

System.out.println("No of days : " + newDate.getDayOfYear() - 1 );    
0
Arnab Bhui