รับวันแรกและวันสุดท้ายของเดือนโดยใช้ threeten, LocalDate


127

ฉันมี LocalDate ซึ่งจำเป็นต้องได้รับวันแรกและวันสุดท้ายของเดือน ฉันจะทำอย่างไร?

เช่น. 13/2/2014 ฉันต้องการรับ1/2/2014และ28/2/2014ในรูปแบบLocalDate

ใช้คลาส LocalDate ที่สาม

คำตอบ:


182

เพียงใช้withDayOfMonthและlengthOfMonth():

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

3
FYI ดูคำตอบอื่น ๆ
assylias

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

90

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
ทางออกที่ดีที่สุดของทั้งหมด
AgustíSánchez

ข้อมูลเพิ่มเติม: YearMonth yearMonth = YearMonth.parse ("202004", DateTimeFormatter.ofPattern ("yyyyMM"));
egemen

ข้อดีของมันเมื่อเทียบกับLocalDate withวิธีการคืออะไร?
AndrewBloom

@AndrewBloom คุณไม่จำเป็นต้องใช้ฟังก์ชันคงที่เพื่อรับวันสุดท้ายของเดือนและอย่างน้อยในตัวอย่างที่สองคุณไม่จำเป็นต้องมีLocalDateอินสแตนซ์เพื่อเริ่มต้นด้วย
herman

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 และชี้ไปที่ส่วนใหม่ที่น่าสนใจเป็นหลักคือตัวปรับเวลาสำหรับสิ้นเดือน นั่นคือฉันไม่ได้ "คัดลอก" คำตอบจากคนอื่น
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);
    }

รหัสที่ดี แต่ใน Stack Overflow คำตอบควรระบุถึงข้อมูลเฉพาะของคำถาม
Basil Bourque

ขอบคุณฉันเห็นด้วย บางครั้งเราพบรหัสที่เกี่ยวข้องในเธรดขณะที่ฉันหาสิ่งนี้เช่นกัน ฉันใส่ไว้สำหรับผู้ใช้ดังกล่าว หวังว่าคงไม่เป็นไร ขอบคุณ
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);

คุณสามารถค้นหาผลลัพธ์ที่ต้องการได้ แต่ต้องดูแลพารามิเตอร์true / falseสำหรับเมธอดgetLastDayOfMonth

พารามิเตอร์นั้นหมายถึงปีอธิกสุรทิน


ไม่จำเป็นต้องใช้getLastDayOfMonth- ดูคำตอบของฉันสำหรับแนวทางที่ง่ายกว่า
Jon Skeet

0

หากคุณต้องการทำเฉพาะกับ LocalDate-class:

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เป็นคลาสผิดที่จะใช้ที่นี่ คุณกำลังทิ้งข้อมูลโซน / ออฟเซ็ตที่มีค่า
Basil Bourque

คำถามจะขอค่าวันที่เท่านั้นไม่ใช่ค่าวันที่กับเวลาที่คุณต้องการที่นี่ และคลาสมรดกที่เลวร้ายDateไม่มีส่วนเกี่ยวข้องกับคำถามและโดยทั่วไปควรหลีกเลี่ยง
Basil Bourque

1
ZoneId.of("America/La_Paz")สำหรับโซนเวลาลาปาซกรุณาใช้ที่ถูกต้องมากขึ้น สำหรับวันที่ปัจจุบันจะให้ผลลัพธ์เช่นเดียวกัน แต่อาจไม่ใช่สำหรับวันที่ในประวัติศาสตร์หรือวันที่ในอนาคตข้างหน้า
Ole VV
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.