英文:
Java Monthly Recurrence
问题
我正在尝试获取特定时期的每月循环日期。以下代码在除了当我指定每月循环日期为30号时有效。然后它会生成以下错误,这是正常的:
Exception in thread "main" java.time.DateTimeException: 无效日期 '二月 30日'
我的问题是:如果指定的循环日期(日)大于该月的最后一天,是否有办法将循环设置为该月的最后一天?
谢谢!
英文:
I am trying to get a monthly recurrence dates for a specific period. The code below works except when I am specifying the recurrence date of 30. Then it is generating the following error, which is normal:
Exception in thread "main" java.time.DateTimeException: Invalid date 'FEBRUARY 30'
My question is : Is there a way to set the recurrence to the last day of the month if the specified date (day) of the recurrence is higher than the last day of the month ?
Thanks !
public class MonthlyRecurrence {
public static void main(String[] args) {
LocalDate startDate = LocalDate.of(2020, 10, 6);
LocalDate endDate = LocalDate.of(2021, 12, 31);
int dayOfMonth = 30;
List<LocalDate> reportDates = getReportDates(startDate, endDate, dayOfMonth);
System.out.println(reportDates);
}
private static List<LocalDate> getReportDates(LocalDate startDate, LocalDate endDate, int dayOfMonth) {
List<LocalDate> dates = new ArrayList<>();
LocalDate reportDate = startDate;
while (reportDate.isBefore(endDate)) {
reportDate = reportDate.plusMonths(1).withDayOfMonth(dayOfMonth);
dates.add(reportDate);
}
return dates;
}
}
答案1
得分: 2
你需要指定一个 TemporalAdjuster 来获取特定日期,而不考虑月份的长度。它作为第三个参数传递给你的方法。
因为我不太确定你想要什么,所以我包含了两个调整器。一个用于特定的日期,另一个用于月末的最后一天。它们可以互换使用。然而,后者不会到达 2021年12月31日
,因为 before
不包括 ==
。
LocalDate startDate = LocalDate.of(2020, 10, 6);
LocalDate endDate = LocalDate.of(2021, 12, 31);
// 用于特定日期的调整器
int dayOfMonth = 30; // 必须是 final 或 effectively final
// 因为它在下面的 lambda 中被使用。
TemporalAdjuster specificDay =
date -> {
LocalDate ld = (LocalDate) date;
int max = ld.getMonth().length(ld.isLeapYear());
int day = dayOfMonth > max ? max : dayOfMonth;
return date.with(ChronoField.DAY_OF_MONTH, day);
};
// 用于月末最后一天的调整器
TemporalAdjuster lastDay = TemporalAdjusters.lastDayOfMonth();
List<LocalDate> reportDates =
getReportDates(startDate, endDate, specificDay);
reportDates.forEach(System.out::println);
private static List<LocalDate> getReportDates(LocalDate startDate,
LocalDate endDate, TemporalAdjuster specificDay) {
List<LocalDate> dates = new ArrayList<>();
// 将开始日期向上调整到特定日期
LocalDate reportDate = startDate.with(specificDay);
while (reportDate.isBefore(endDate)) {
dates.add(reportDate);
reportDate = reportDate.plusMonths(1).with(specificDay);
}
return dates;
}
根据选择的 TemporalAdjuster
打印如下内容:
SpecificDay (30th) LastDayOfMonth
2020-10-30 2020-10-31
2020-11-30 2020-11-30
2020-12-30 2020-12-31
2021-01-30 2021-01-31
2021-02-28 2021-02-28
2021-03-30 2021-03-31
2021-04-30 2021-04-30
2021-05-30 2021-05-31
2021-06-30 2021-06-30
2021-07-30 2021-07-31
2021-08-30 2021-08-31
2021-09-30 2021-09-30
2021-10-30 2021-10-31
2021-11-30 2021-11-30
2021-12-30
英文:
You need to specify a TemporalAdjuster to get the specific day of the month regardless of the month's length. It is passed as the third argument to your method.
Because I wasn't quite certain what you wanted, I included two adjusters. One for a specific day and one for the last day of the month. They can be used interchangeably. However, the latter will not reach Dec 31, 2021
since the before
excludes ==
LocalDate startDate = LocalDate.of(2020, 10, 6);
LocalDate endDate = LocalDate.of(2021, 12, 31);
// Adjuster for a specific day
int dayOfMonth = 30; // must be final or effectively final
// as it is used in the following lambda.
TemporalAdjuster specificDay =
date-> {
LocalDate ld = (LocalDate)date;
int max = ld.getMonth().length(ld.isLeapYear());
int day = dayOfMonth > max ? max : dayOfMonth;
return date.with(ChronoField.DAY_OF_MONTH,day);
};
// Adjuster for the lastDay of the month.
TemporalAdjuster lastDay = TemporalAdjusters.lastDayOfMonth();
List<LocalDate> reportDates =
getReportDates(startDate, endDate, specificDay);
reportDates.forEach(System.out::println);
private static List<LocalDate> getReportDates(LocalDate startDate,
LocalDate endDate, TemporalAdjuster specificDay) {
List<LocalDate> dates = new ArrayList<>();
// round up start day to specificDay
LocalDate reportDate = startDate.with(specificDay);
while (reportDate.isBefore(endDate)) {
dates.add(reportDate);
reportDate = reportDate.plusMonths(1).with(specificDay);
}
return dates;
}
Prints the following depending on choice of TemporalAdjuster
SpecificDay (30th) LastDayOfMonth
2020-10-30 2020-10-31
2020-11-30 2020-11-30
2020-12-30 2020-12-31
2021-01-30 2021-01-31
2021-02-28 2021-02-28
2021-03-30 2021-03-31
2021-04-30 2021-04-30
2021-05-30 2021-05-31
2021-06-30 2021-06-30
2021-07-30 2021-07-31
2021-08-30 2021-08-31
2021-09-30 2021-09-30
2021-10-30 2021-10-31
2021-11-30 2021-11-30
2021-12-30
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论