使用Threeten LocalDate获取每月的第一天和最后一天


125

我有一个LocalDate,需要获取该月的第一天和最后一天。我怎么做?

例如。13/2/2014 我需要1/2/201428/2/2014LOCALDATE的格式。

使用threeten LocalDate类。

Answers:


178

只需使用withDayOfMonthlengthOfMonth()

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

3
仅供参考,其他答案
assylias 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

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

LocalDate with方法相比有什么优点?
AndrewBloom

@AndrewBloom不需要使用静态函数来获取月份的最后一天,至少在第二个示例中,您不需要从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)早一天,并且指出了主要有趣的新部分,即月底的时间调整器。那就是我还没有“复制”任何其他人的答案。
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中,Answer应该解决问题的细节。
罗勒·布尔克

谢谢,我同意。有时我们也在线程中找到相关的代码。我只是为这类用户准备的。希望没事。谢谢。
阿尼尔·巴斯卡

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方法

该参数表示leap年


无需使用getLastDayOfMonth-有关更简单方法的信息,请参见我的答案。
乔恩·斯基特

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.