Threeten、LocalDateを使用して月の最初と最後の日を取得する


126

月の最初と最後の日を取得する必要があるLocalDateがあります。それ、どうやったら出来るの?

例えば。13/2/2014 私が取得する必要があります1/2/2014し、28/2/2014LOCALDATEのフォーマット。

Threeten LocalDateクラスを使用します。

回答:


179

とを使用withDayOfMonthしてlengthOfMonth()ください:

LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.withDayOfMonth(1);
LocalDate end = initial.withDayOfMonth(initial.lengthOfMonth());

3
参考までに、他の回答を参照してください
アサイリア2014

147

APIは、ビジネス要件に厳密に一致するソリューションをサポートするように設計されました

import static java.time.temporal.TemporalAdjusters.*;

LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.with(firstDayOfMonth());
LocalDate end = initial.with(lastDayOfMonth());

ただし、ジョンのソリューションも問題ありません。


5
これと一緒に、この特定の問題を処理するために特別に作成されたAPIリソースを使用します。
jpangamarca 2017

87

YearMonth

完全性のために、そして私の意見ではよりエレガントに、YearMonthクラスのこの使用法を参照してください。

YearMonth month = YearMonth.from(date);
LocalDate start = month.atDay(1);
LocalDate end   = month.atEndOfMonth();

今月の最初と最後の日は、次のようになります。

LocalDate start = YearMonth.now().atDay(1);
LocalDate end   = YearMonth.now().atEndOfMonth();

8
すべての最良のソリューション。
アグスティ・サンチェス

追加情報:YearMonth yearMonth = YearMonth.parse( "202004"、DateTimeFormatter.ofPattern( "yyyyMM"));
エジェメン

LocalDate withメソッドと比較してそれの利点は何ですか?
AndrewBloom

@AndrewBloomでは、月の最終日を取得するために静的関数を使用する必要はありません。少なくとも2番目の例では、LocalDate最初にインスタンスを用意する必要はありません。
ヘルマン

18

Jon Skeetsの答えは正しく、完全性のためにこのわずかに異なるソリューションを追加するだけで、私の賛成に値します。

import static java.time.temporal.TemporalAdjusters.lastDayOfMonth;

LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.withDayOfMonth(1);
LocalDate end = initial.with(lastDayOfMonth());

2
正直なところ、私の投票はJodaStephenの1日前でさえあり、主に興味深い新しい部分、つまり月末の時間調整器を指摘していたため、正直に言って、私は反対票を理解していません。それは私が他の誰かからの答えを「コピー」していないということです。
Meno Hochschild、

正解です。それはにお勧めしますので、このソリューションは優れているドキュメント「...月の最初または最後の日を見つける」:
peterchaula

4

誰が来た場合を探して、前の月の最初の日、前の月の最後の日

public static LocalDate firstDayOfPreviousMonth(LocalDate date) {
        return date.minusMonths(1).withDayOfMonth(1);
    }


public static LocalDate lastDayOfPreviousMonth(LocalDate date) {
        return date.withDayOfMonth(1).minusDays(1);
    }

良いコードですが、スタックオーバーフローでは、回答は質問の詳細に対処する必要があります。
バジルブルク2018

ありがとう、同意する。私もこれを探していたので、スレッドに関連コードが見つかることがあります。私はそのようなユーザーのためにそれを置きました。大丈夫だと思います。ありがとう。
Anil Bhaskar、

3
 LocalDate monthstart = LocalDate.of(year,month,1);
 LocalDate monthend = monthstart.plusDays(monthstart.lengthOfMonth()-1);

あなたの答えを説明してください
smilyface

1

これを試して、カスタム日付の表示を避け、現在の月の開始日と終了日を表示する必要がある場合は、次のようにしてください。

    LocalDate start = LocalDate.now().minusDays(LocalDate.now().getDayOfMonth()-1);
    LocalDate end = LocalDate.now().minusDays(LocalDate.now().getDayOfMonth()).plusMonths(1);
    System.out.println("Start of month: " + start);
    System.out.println("End of month: " + end);

結果:

>     Start of month: 2019-12-01
>     End of month: 2019-12-30

1
私には少し複雑すぎるようです。また、正しい結果も得られません。今月の最終日は2019-12-31ですが、スニペットは2019-12-30と印刷されています。
Ole VV

0

これを試して:

LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.withDayOfMonth(1);         
LocalDate end = initial.withDayOfMonth(initial.getMonthOfYear().getLastDayOfMonth(false));
System.out.println(start);
System.out.println(end);

欲求の出力を見つけることができますが、getLastDayOfMonthメソッドのパラメーターtrue / false処理する必要があります

そのパラメーターはうるう年を表します


使用する必要はありませんgetLastDayOfMonth-簡単なアプローチについては私の答えを参照してください。
Jon Skeet、2014年

0

LocalDateクラスのみで実行する場合:

LocalDate initial = LocalDate.of(2014, 2, 13);

LocalDate start = LocalDate.of(initial.getYear(), initial.getMonthValue(),1);

// Idea: the last day is the same as the first day of next month minus one day.
LocalDate end = LocalDate.of(initial.getYear(), initial.getMonthValue(), 1).plusMonths(1).minusDays(1);

0

@hermanソリューションの実装をここに示します

ZoneId americaLaPazZone = ZoneId.of("UTC-04:00");

static Date firstDateOfMonth(Date date) {
  LocalDate localDate = convertToLocalDateWithTimezone(date);
  YearMonth baseMonth = YearMonth.from(localDate);
  LocalDateTime initialDate = baseMonth.atDay(firstDayOfMonth).atStartOfDay();
  return Date.from(initialDate.atZone(americaLaPazZone).toInstant());
}

static Date lastDateOfMonth(Date date) {
  LocalDate localDate = convertToLocalDateWithTimezone(date);
  YearMonth baseMonth = YearMonth.from(localDate);
  LocalDateTime lastDate = baseMonth.atEndOfMonth().atTime(23, 59, 59);
  return Date.from(lastDate.atZone(americaLaPazZone).toInstant());
}

static LocalDate convertToLocalDateWithTimezone(Date date) {
  return LocalDateTime.from(date.toInstant().atZone(americaLaPazZone)).toLocalDate();
}

LocalDateTimeここで使用するクラスはまったく間違っています。貴重なゾーン/オフセット情報を破棄しています。
バジルブルク

質問では、ここで検索する日時付きの値ではなく、日付のみの値を要求します。そして、ひどいレガシークラスDateは質問とは何の関係もないので、一般的には避けるべきです。
バジルブルク

1
ラパスのタイムゾーンについては、より正確なものを使用してくださいZoneId.of("America/La_Paz")。現在の日付では同じ結果が得られますが、おそらく過去の日付や将来の日付ではありません。
Ole VV
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.