java - 日历行为与 LocalDate 不兼容?
问题描述
嗨伙计们,我在尝试将行为从日历迁移到本地日期时遇到了麻烦。
payDate.set(Calendar.DAY_OF_MONTH,payDay)
让我们假设payDate
当前日期为 2020-01-29
由于业务原因payDay
可以0
取值payDate
为过去一个月。
我不确定这是技术原因,如果有人可以向我解释这一点,我将非常感激,我尝试检查 java 文档,但没有帮助。
所以我需要用 LocalDate java 库复制这种行为。从我的角度来看; 与LocalDate 中的值类似的set
方法是:Calendar
DAY_OF_MONTH
payDate.withDayOfMonth(payDay)
但是当出现以下场景并且payDay
等于0
我得到一个错误时:
java.time.DateTimeException: Invalid value for DayOfMonth (valid values 1 - 28/31): 0
我也有一些想法,关于如何在规则生效时在 localDate 中获得相同的日历结果(如果 payDay 为 0,则返回上个月的最后一天),但过于冗长。
如果您知道 LocalDate 上的类似行为,请帮助我。谢谢。
解决方案
TL;DR:使用payDate = payDate.plusDays(payDay - payDate.getDayOfMonth());
Calendar
您所描述的行为记录在 javadoc 中:
宽大
Calendar
有两种解释日历字段的模式,lenient和non-lenient。当 aCalendar
处于宽松模式时,它接受的日历字段值范围比它产生的范围更广。当 aCalendar
为 return by 重新计算日历字段值时get()
,所有日历字段都被规范化。例如,宽大的人将,GregorianCalendar
解释为 2 月 1 日。MONTH == JANUARY
DAY_OF_MONTH == 32
当 a
Calendar
处于非宽松模式时,如果其日历字段中存在任何不一致,它将引发异常。例如,aGregorianCalendar
总是产生DAY_OF_MONTH
介于 1 和月份长度之间的值。如果设置了任何超出范围的字段值,则non-lenientGregorianCalendar
在计算其时间或日历字段值时会引发异常。
要显示此效果,请尝试将 a 的日期设置为Calendar
2020 年 1 月 70 日:
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(2020, Calendar.JANUARY, 70);
System.out.println(new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime()));
输出
2020-03-10
如果你这样做,你会得到相同的结果:
cal.set(2020, Calendar.JANUARY, 1);
cal.add(Calendar.DAY_OF_MONTH, 69);
LocalDate
总是non-lenient,因此您不能将 day-of-month 值设置为超出范围的值。Calendar
但是,您可以通过将操作更改为“添加”而不是“设置”来获得与实际操作相同的结果。
因此,如果您有一个特定的日期,例如2020-01-29
问题中提到的日期,并且您想将日期值“设置”为 70 或 0,并且具有与之前相同的宽松溢出逻辑Calendar
,请执行以下操作:
LocalDate date = LocalDate.parse("2020-01-29");
date = date.plusDays(70 - date.getDayOfMonth());
System.out.println(date);
LocalDate date = LocalDate.parse("2020-01-29");
date = date.plusDays(0 - date.getDayOfMonth());
System.out.println(date);
输出
2020-03-10
2019-12-31
如您所见,date.plusDays(dayToSet - date.getDayOfMonth())
将为您提供所需的结果。
推荐阅读
- laravel - 随机 [access_compat:error] AH01797:客户端被 apache 的 error.log 文件中的服务器配置错误拒绝
- quill - 羽毛笔 JS | 实现多页面功能
- google-sheets - 如何将查询/过滤公式转换为数组公式?
- android - 关于如何用 JobIntentService 替换 IntentService 的 CSV 导出示例
- rate - 如何获得普拉特的出水率?
- python-3.x - 图像未从表单发布请求在 django 中更新
- arrays - 有没有办法在postgresql的“值数组”中查询带有某些条件的jsonb列?
- python - 如何使用第一个字母作为参数从列表/系列/数据框中过滤单词?
- odoo - 添加动作以下载txt文件
- linux - 来自 Linux 中 AP(接入点)的客户端列表(站)命令