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

我有一个 LocalDate,它需要得到每月的第一天和最后一天。 我该怎么做?

例如 13/2/2014 我需要得到 1/2/201428/2/2014LocalDate格式。

使用13个 LocalDate 类。

160153 次浏览

只要使用 withDayOfMonthlengthOfMonth():

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

试试这个:

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 每月最后一天方法的参数 真/假

那个参数代表闰年

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

API 被设计为支持与业务需求紧密匹配的解决方案

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


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

然而,Jon 的解决方案也不错。

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

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

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




public static LocalDate lastDayOfPreviousMonth(LocalDate date) {
return date.withDayOfMonth(1).minusDays(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);

只是在这里展示我的@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();
}

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

    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
 LocalDate monthstart = LocalDate.of(year,month,1);
LocalDate monthend = monthstart.plusDays(monthstart.lengthOfMonth()-1);
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

这个月最后一天的另一个解决方案是:

我写这个答案只是为了学习者谁想学习通过玩各种选择

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,一个月的最大天数可以有,这个工程的所有月份。

Rel = “ nofollow noReferrer”> Trail: Date Time 了解有关 现代日期时间 API*的更多信息。


* 如果您正在为 Android 项目工作,并且您的 Android API 级别仍然不符合 Java-8,请检查 Java8 + API 可以通过去糖化获得。请注意,Android 8.0奥利奥已经提供了 java.time的支持。检查 这个答案这个答案以了解如何在 JDBC 中使用 java.time API。

与 DayOfMonth 一起使用。 Now () . withDayOfMonth (1) 这将给月初。