使用 LocalDateTime
或 LocalDate
将月份添加到指定日期的最干净的解决方案是什么?
不错的答案是 In java.time, how is the result of adding a month calculated?和 Find next occurrence of a day-of-week in JSR-310所以我希望这个问题可以用类似的干净解决方案来解决。
假设用户选择一个月中的某一天(从 1 到 31 中的任意一天)执行某个周期性任务。选择时间戳后生成并每月增加。仅存储当前月份的时间戳(没有上个月的轨迹,时间戳每月更新)和选定的月份日期。
如果选择的日期是31 日 并且我们从1 月31 日 开始,使用dateTime.plusMonths(1)
方法添加一个月会得到 2016 年 2 月 29 日。如果再次使用 dateTime.plusMonths(1)
方法,结果为 3 月 29 日,而预期为 3 月 31 日。但是,它适用于从 1 日到 28 日的几天。
每月第 31 天的解决方法可以使用 dateTime.with(TemporalAdjusters.lastDayOfMonth())
但这不包括从 28 日到 30 日的日子,这也可能是一个月的最后几天。
lastDayOfMonth()
示例,用于选择月中的第 30 日:1 月 30 日、2 月 29 日(plusMonth如果前一天高于上个月,方法行为会选择最后一天),3 月 31 日(预计是 30 日,这是一个月中的选定日期)。此方法不考虑一个月中选定的几天。
当然,这个问题有很多潜在的解决方案,包括一些检查和计算月与日之间的差异,但我正在寻找一种仅在可能的情况下使用 java.time 功能的解决方案。
澄清
我正在寻找一种方法来将日期移动到下个月的选定日期。像 dateTime.plusMonths(1).withDayOfMonth(selectedDayOfMonth)
。对于像 2 月 31 日这样的日期,这将引发异常,因为 withDayOfMonth
会覆盖 plusMonths
对最后有效日期的调整。
使用 plusMonth
方法的迭代示例。在迭代中,取前一个的值 - 想象一下递归。
+-----------+------------------+---------------+
| iteration | Day-of-month: 31 | Expected |
+-----------+------------------+---------------+
| 1 | January 31st | January 31st |
| 2 | February 29th | February 29th |
| 3 | March 29th | March 31st |
| 4 | April 29th | April 30th |
+-----------+------------------+---------------+
另一个工作示例是从 1 号到 28 号。
+-----------+-------------------+--------------+
| iteration | Day-of-month: 4th | Expected |
+-----------+-------------------+--------------+
| 1 | January 4th | January 4th |
| 2 | February 4th | February 4th |
| 3 | March 4th | March 4th |
| 4 | April 4th | April 4th |
+-----------+-------------------+--------------+
月 29 日适用于闰年,但不适用于平年。
+-----------+--------------------+---------------+
| iteration | Day-of-month: 29th | Expected |
+-----------+--------------------+---------------+
| 1 | January 29th | January 29th |
| 2 | February 28th | February 28th |
| 3 | March 28th | March 29th |
| 4 | April 28th | April 29th |
+-----------+--------------------+---------------+
最佳答案
将月中的第几天设置为 min(selectedDayOfMonth, lastDayOfNextMonth)
public static LocalDate next(LocalDate current, int selectedDayOfMonth) {
LocalDate next = current.plusMonths(1);
return next.withDayOfMonth(Math.min(selectedDayOfMonth, next.lengthOfMonth()));
}
用法:
public static void test(int selectedDayOfMonth) {
LocalDate date = LocalDate.of(2001, Month.JANUARY, selectedDayOfMonth);
System.out.println(date);
for (int i = 0; i < 5; i++) {
date = next(date, selectedDayOfMonth);
System.out.println(date);
}
System.out.println();
}
test(4)
的输出:
2001-01-04
2001-02-04
2001-03-04
2001-04-04
2001-05-04
2001-06-04
test(29)
的输出:
2001-01-29
2001-02-28
2001-03-29
2001-04-29
2001-05-29
2001-06-29
test(31)
的输出:
2001-01-31
2001-02-28
2001-03-31
2001-04-30
2001-05-31
2001-06-30
关于java - 使用 java.time 将月份添加到每月的特定日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39046324/