web-dev-qa-db-ja.com

うるう年を説明するJava8期間を1年にする方法はありますか?

1年の日数が必要で、Java8の新しい時間APIを使用したいと思っていました。

ただし、うるう年を考慮していないため、Duration.ofDays(365)を実行できません。そしてDuration.of(1, ChronoUnit.YEARS)Java.time.temporal.UnsupportedTemporalTypeException: Unit must not have an estimated durationのために飛ばない

ピリオドを調べましたが、年から日への移行には役立ちません。

ここで何か不足しているように感じますか?うるう年の場合は、日を追加する何かを書くこともできますが、これはすぐに処理できるはずです。

33
user2272115

新しいdateTime APIを使用した期間の取得 の応答に従って、使用する必要があります

Period p = Period.ofYears(1);

Duration(正確なナノ秒数<1日)とPeriod(変数> 1日)の違いを理解することが重要です。

Durationは、うるう日、夏時間、うるう秒などを考慮せず、1日未満、多くても数日を対象としています。したがって、代わりにPeriodを使用できれば、さらに優れています。

年によって日数が異なるため、1年の日数を調べるには、話している年を指定する必要があります。

特定の年の日数が必要な場合は、

Year.of(year).length()

1年後の日付が必要な場合は、

LocalDate.now().plusYears(1)

または

LocalDate.now().plus(Period.ofYears(1))

2つの日付間の日数が必要な場合は、

ChronoUnit.DAYS.between(start, end)

したがって、1年後までの日数を求めるには、

LocalDate today = LocalDate.now();
long days = ChronoUnit.DAYS.between(today, today.plusYears(1));

1年間のメンバーシップがまだ有効かどうかを確認したい場合は、

Period membershipLength = Period.ofYears(1);
LocalDate membershipStart = ...;
LocalDate membershipEnd = membershipStart.plus(membershipLength);

LocalDate today = LocalDate.now();
boolean memberShipEnded = today.isAfter(membershipEnd);
boolean membershipValid = !membershipEnded;

期間(= 2つの日付の間)ではなく、特定の日付の年の長さを必要としないことは明らかです。

_LocalDate dateLeap = LocalDate.of(2004, Month.MARCH, 1);
System.out.println("leap year of " + dateLeap
    + " has days: " + dateLeap.lengthOfYear());
_

2004-03-01のうるう年には日数があります:366

Java 8の日付と時刻は驚くほど完全です。


つまり、2004年1月5日から2005年1月5日= 66および2004年3月2日から2005年3月2日= 65

_int lengthOfYear(LocalDate date) {
    return date.getMonthValue() <= 2
        ? date.lengthOfYear()               // Count Feb in this year
        : date.plusYears(1).lengthOfYear(); // Count Feb in next year
}
_

説明:基本的に長さは365です。ただし、日付が3月以上の場合は翌年の2月がカウントされ、それ以外の場合は今年の2月がカウントされます。

plusYears(1)はDAYまたはMONTHを変更しないことに注意してください。

また、2月29日のうるう秒も時間/分も考慮されません。

9
Joop Eggen