Dapatkan hari pertama dan terakhir bulan menggunakan tiga, LocalDate


127

Saya memiliki LocalDate yang perlu mendapatkan hari pertama dan terakhir setiap bulan. Bagaimana aku melakukan itu?

misalnya. 13/2/2014 Saya perlu mendapatkan 1/2/2014dan 28/2/2014dalam format LocalDate .

Menggunakan tiga kelas LocalDate.

Jawaban:


180

Cukup gunakan withDayOfMonth, dan lengthOfMonth():

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

3
FYI melihat jawaban lain
assylias

147

API dirancang untuk mendukung solusi yang sesuai dengan kebutuhan bisnis

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

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

Namun, solusi Jon juga bagus.


5
Dengan yang ini, menggunakan sumber daya API yang secara khusus dibuat untuk menangani masalah khusus ini.
jpangamarca

87

YearMonth

Untuk kelengkapan, dan lebih elegan menurut saya, lihat penggunaan YearMonthclass ini.

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

Untuk hari pertama & terakhir bulan ini, ini menjadi:

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

8
Solusi terbaik dari semuanya.
Agustí Sánchez

Info tambahan: YearMonth yearMonth = YearMonth.parse ("202004", DateTimeFormatter.ofPattern ("yyyyMM"));
egemen

Apa kelebihannya dibandingkan dengan LocalDate withmetode?
AndrewBloom

@AndrewBloom Anda tidak perlu menggunakan fungsi statis untuk mendapatkan hari terakhir setiap bulan, dan setidaknya di contoh kedua, Anda tidak perlu memiliki LocalDateinstance untuk memulai.
herman

18

Jawaban Jon Skeets benar dan pantas mendapat suara positif saya, hanya menambahkan solusi yang sedikit berbeda ini untuk kelengkapan:

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
Dear downvoter, sejujurnya, saya tidak mengerti downvote karena jawaban saya bahkan satu hari sebelum JodaStephen dan menunjuk pada part baru yang paling menarik, yaitu temporal adjuster untuk akhir bulan. Artinya saya belum "menyalin" jawaban dari orang lain.
Meno Hochschild

Jawaban yang bagus! Solusi ini lebih baik karena direkomendasikan di dokumen : "... menemukan hari pertama atau terakhir setiap bulan"
peterchaula

4

Jika ada yang datang mencari hari pertama bulan sebelumnya dan hari terakhir bulan sebelumnya :

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


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

Kode yang bagus, tetapi dalam Stack Overflow, sebuah Answer harus membahas pertanyaan spesifik.
Basil Bourque

Terima kasih, saya setuju. Terkadang kami menemukan kode terkait di utas, karena saya juga mencari ini. Saya hanya menaruhnya untuk pengguna seperti itu. Semoga tidak apa-apa. Terima kasih.
Anil Bhaskar

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

Tolong jelaskan jawaban Anda
wajah tersenyum

1

Anda dapat mencoba ini untuk menghindari menunjukkan tanggal kustom dan jika perlu menampilkan tanggal mulai dan akhir bulan ini:

    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);

Hasil:

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

1
Sepertinya agak terlalu rumit bagiku. Itu juga tidak memberikan hasil yang benar. Hari terakhir bulan ini adalah 31-12-2019, tetapi cuplikan Anda dicetak pada 2019-12-30.
Ole VV

0

Coba ini:

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);

Anda dapat menemukan keluaran yang diinginkan tetapi perlu menjaga parameter true / false untuk metode getLastDayOfMonth

parameter itu menunjukkan tahun kabisat


Tidak perlu menggunakan getLastDayOfMonth- lihat jawaban saya untuk pendekatan yang lebih sederhana.
Jon Skeet

0

jika Anda ingin melakukannya hanya dengan kelas 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

Hanya di sini untuk menunjukkan implementasi saya untuk solusi @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();
}

LocalDateTimeadalah kelas yang salah untuk digunakan di sini. Anda membuang informasi zona / offset yang berharga.
Basil Bourque

Pertanyaan meminta nilai tanggal-saja, bukan nilai tanggal-dengan-waktu yang Anda cari di sini. Dan kelas warisan yang mengerikan Datetidak ada hubungannya dengan Pertanyaan tersebut, dan umumnya harus dihindari.
Basil Bourque

1
Untuk zona waktu La Paz, gunakan yang lebih tepat ZoneId.of("America/La_Paz"). Untuk tanggal hari ini akan memberikan hasil yang sama, tetapi mungkin tidak untuk tanggal bersejarah atau tanggal di masa mendatang.
Ole VV
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.