Java 月度重复发生

huangapple go评论57阅读模式
英文:

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-&gt; {
	        LocalDate ld = (LocalDate)date;
	        int max = ld.getMonth().length(ld.isLeapYear());
	        int day = dayOfMonth &gt; max ? max : dayOfMonth;
	        return date.with(ChronoField.DAY_OF_MONTH,day);
};
		
		
// Adjuster for the lastDay of the month.
TemporalAdjuster lastDay = TemporalAdjusters.lastDayOfMonth();
	
List&lt;LocalDate&gt; reportDates =
		getReportDates(startDate, endDate, specificDay);

reportDates.forEach(System.out::println);
	
private static List&lt;LocalDate&gt; getReportDates(LocalDate startDate,
		LocalDate endDate, TemporalAdjuster specificDay) {
	List&lt;LocalDate&gt; dates = new ArrayList&lt;&gt;();
	
	// 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>



huangapple
  • 本文由 发表于 2020年10月18日 07:06:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/64408194.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定