我有一个 LocalDate 需要获取该月的第一天和最后一天。我怎么做?
例如。13/2/2014
我需要获取1/2/2014
和LocalDate格式28/2/2014
。
使用三个 LocalDate 类。
只需使用withDayOfMonth
, 和lengthOfMonth()
:
LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.withDayOfMonth(1);
LocalDate end = initial.withDayOfMonth(initial.lengthOfMonth());
API 旨在支持与业务需求紧密匹配的解决方案
import static java.time.temporal.TemporalAdjusters.*;
LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.with(firstDayOfMonth());
LocalDate end = initial.with(lastDayOfMonth());
但是,乔恩的解决方案也很好。
YearMonth
为了完整性,我认为更优雅,请参阅YearMonth
class 的这种用法。
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();
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());
LocalDate monthstart = LocalDate.of(year,month,1);
LocalDate monthend = monthstart.plusDays(monthstart.lengthOfMonth()-1);
如果有人来寻找上个月的第一天和上个月的最后一天:
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 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
该函数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.time
API 与 JDBC 一起使用。
您可以尝试这样做以避免指示自定义日期以及是否需要显示当前月份的开始和结束日期:
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 类:
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);
尝试这个:
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
该参数表示闰年
只是在这里展示我对@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();
}