3

假设 2000 年 1 月 31 日是闰年,以下两种添加月份的方法给了我不同的结果。我做错了什么还是这两种处理闰年月份的不同理念?而且,如果这两种方法只是哲学上的差异,你怎么知道选择哪种方法?

方法1:使用LocalDate plusMonths()

LocalDate atestDate = LocalDate.parse("2000-01-31");
System.out.println("One month in future using LocalDate.addMonths() " +   atestDate.plusMonths(1));

输出:

One month in future using LocalDate.addMonths() 2000-02-29

方法2:使用Calendar

Calendar zcal = Calendar.getInstance();
zcal.set(Calendar.DAY_OF_MONTH, 31);
zcal.set(Calendar.MONTH, 1);
zcal.set(Calendar.YEAR, 2000);
zcal.add(Calendar.MONTH, 0);
System.out.println("ONE MONTH IN FUTURE using Calendar: " 
 + zcal.getTime());

输出:

ONE MONTH IN FUTURE using Calendar: Thu Mar 02 2000 

为什么这两个日期的输出不一样?

谢谢。

4

3 回答 3

3
zcal.set(Calendar.DAY_OF_MONTH, 31);
zcal.set(Calendar.MONTH, 1);
zcal.set(Calendar.YEAR, 2000);

这定义了 2000 年 2 月 31 日的日期,由于宽松的测量,它等于 2000 年 3 月 2 日。月份值是零索引的。

设置严格:

zcal.setLenient(false);

我们得到一个例外:

Exception in thread "main" java.lang.IllegalArgumentException: MONTH: 1 -> 2
at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2829)
at java.util.Calendar.updateTime(Calendar.java:3393)
at java.util.Calendar.getTimeInMillis(Calendar.java:1782)
at java.util.Calendar.getTime(Calendar.java:1755)
at Employee.Tester.main(Tester.java:19)

所以你可以看到插值转移到了三月。如果您希望对日期进行硬编码以进行测试,我建议您使用严格验证来避免这些情况。还有其他记录在案的问题与设置值有关,这些问题会使事情变得混乱。

于 2018-04-27T17:28:17.780 回答
2
于 2018-04-27T21:48:09.560 回答
1

我在上面的帖子中遇到的问题原来是一个错字。

Calendar zcal = Calendar.getInstance();
zcal.set(Calendar.DAY_OF_MONTH, 31);
zcal.set(Calendar.MONTH, 1);
zcal.set(Calendar.YEAR, 2000);
zcal.add(Calendar.MONTH, 0);
System.out.println("ONE MONTH IN FUTURE using Calendar: " 
 + zcal.getTime());

本来应该:

Calendar zcal = Calendar.getInstance();
zcal.set(Calendar.DAY_OF_MONTH, 31);
zcal.set(Calendar.MONTH, Calendar.JANUARY);
zcal.set(Calendar.YEAR, 2000);
zcal.add(Calendar.MONTH, 1);
System.out.println("ONE MONTH IN FUTURE using Calendar: " 
 + zcal.getTime());

然后我得到预期的匹配日期。

感谢所有回答的人!:)

于 2018-04-27T21:32:21.410 回答