166

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

例如。13/2/2014 我需要获取1/2/2014LocalDate格式28/2/2014

使用三个 LocalDate 类。

4

12 回答 12

237

只需使用withDayOfMonth, 和lengthOfMonth():

LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.withDayOfMonth(1);
LocalDate end = initial.withDayOfMonth(initial.lengthOfMonth());
于 2014-03-06T12:00:36.750 回答
186

API 旨在支持与业务需求紧密匹配的解决方案

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

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

但是,乔恩的解决方案也很好。

于 2014-03-07T01:47:37.363 回答
126

YearMonth

为了完整性,我认为更优雅,请参阅YearMonthclass 的这种用法。

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();
于 2018-04-18T09:21:55.473 回答
21

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());
于 2014-03-06T14:22:07.123 回答
7
 LocalDate monthstart = LocalDate.of(year,month,1);
 LocalDate monthend = monthstart.plusDays(monthstart.lengthOfMonth()-1);
于 2020-01-17T15:26:40.067 回答
5

如果有人来寻找上个月的第一天和上个月最后一天

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-12-27T16:39:40.170 回答
4
LocalDate endDate = startDate.withDayOfMonth(1).plusMonths(1).minusDays(1);

或者

    LocalDate startDate = LocalDate.now();
    System.out.println("startDate: "+startDate);
    
    LocalDate firstDayOfMonth_of_startDate = startDate.withDayOfMonth(1); 
    System.out.println("firstDayOfMonth_of_startDate: "+firstDayOfMonth_of_startDate);
    
    LocalDate firstDayOfNextMonth_of_startDate = firstDayOfMonth_of_startDate.plusMonths(1); 
    System.out.println("firstDayOfNextMonth_of_startDate: "+firstDayOfNextMonth_of_startDate);
    
    LocalDate lastDayOfTheMonth_of_startDate = firstDayOfNextMonth_of_startDate.minusDays(1); 
    System.out.println("lastDayOfTheMonth_of_startDate: "+lastDayOfTheMonth_of_startDate);

    // or everything in one line
    LocalDate endDate = startDate.withDayOfMonth(1).plusMonths(1).minusDays(1);
    System.out.println("endDate: "+endDate);

和打印输出

startDate: 2021-11-05
firstDayOfMonth_of_startDate: 2021-11-01
firstDayOfNextMonth_of_startDate: 2021-12-01
lastDayOfTheMonth_of_startDate: 2021-11-30
endDate: 2021-11-30
于 2021-11-04T16:25:46.907 回答
2

本月最后一天的另一种解决方案:

我为想要通过玩各种选项来学习的学习者写了这个答案。我不建议将其用于生产用途。

import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        //Test
        System.out.println(lastDateOfMonth(LocalDate.of(2014, 1, 13)));
        System.out.println(lastDateOfMonth(LocalDate.of(2014, 2, 13)));
        System.out.println(lastDateOfMonth(LocalDate.of(2016, 2, 13)));
        System.out.println(lastDateOfMonth(LocalDate.of(2014, 4, 13)));
    }
    
    static LocalDate lastDateOfMonth(LocalDate date) {
        DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                                .parseDefaulting(ChronoField.DAY_OF_MONTH, 31)
                                .appendPattern("uuuu-MM")
                                .toFormatter(Locale.ENGLISH);
        return LocalDate.parse(YearMonth.from(date).toString(), dtf);
    }
}

输出:

2014-01-31
2014-02-28
2016-02-29
2014-04-30

ONLINE DEMO

它是如何工作的?

该函数YearMonth#toString返回一个格式为 的字符串,uuuu-MM该格式是我与DateTimeFormatterBuilder. 我已经默认ChronoField.DAY_OF_MONTH为 31 天,一个月可以有的最大天数,这适用于所有月份。

Trail: Date Time了解有关现代日期时间 API *的更多信息。


* 如果您正在为一个 Android 项目工作,并且您的 Android API 级别仍然不符合 Java-8,请通过 desugaring 检查可用的 Java 8+ API。请注意,Android 8.0 Oreo 已经提供java.time. 检查此答案此答案以了解如何将java.timeAPI 与 JDBC 一起使用。

于 2021-11-05T17:54:05.070 回答
2

您可以尝试这样做以避免指示自定义日期以及是否需要显示当前月份的开始和结束日期:

    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
于 2019-12-04T12:49:19.727 回答
1

如果您只想使用 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);
于 2019-02-21T17:02:30.457 回答
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

该参数表示闰年

于 2014-03-06T12:46:34.587 回答
-1

只是在这里展示我对@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();
}
于 2019-09-21T03:24:23.683 回答