小小的脑袋有一个大大的疑惑??6月有31日吗?
小幸今天在用java刷算法题的时候,偶然间用到Calendar这个类,想借用他的日历功能计算某一天后的n天的日期,谁知却有惊奇的发现,直接上代码。
import java.util.Calendar;
public class Main {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
calendar.set(2020, 6, 1);
// calendar.set(2020, 2, 1);
calendar.add(Calendar.DATE, 30);
System.out.println(calendar.get(Calendar.YEAR)+"-"+calendar.get(Calendar.MONTH)
+"-"+calendar.get(Calendar.DATE));
}
}
本例中,我想计算2020年6月1日后的第30天的日期,正确的答案应该是2020-7-1。万万没想到,这段代码给出的答案却是2020-6-31,顿时我就纳闷了,6月是大月?有31号?我不知道这是我知识的盲区,还是该类在处理的时候没有考虑到这些呢?后边小幸还测试了2月,发现竟然会输出2020-2-31,真的是刷新我的认识。于是我修改增加的天数,发现天数改动之后,其间只会有这样的一个日期出错,下一年遇到改天的时候会正确转为下一月,这就让我顿生疑惑,难到api指定了最多只能错一次?
为了搞明白这是为何,到底是认知问题还是有意为之,我进一步查看了Calendar这个类,发现这是个抽象类,add方法调用roll方法,而roll方法在声明的时候给出了如下注释:
/**
* Adds or subtracts (up/down) a single unit of time on the given time
* field without changing larger fields. For example, to roll the current
* date up by one day, you can achieve it by calling:
* <p>roll(Calendar.DATE, true).
* When rolling on the year or Calendar.YEAR field, it will roll the year
* value in the range between 1 and the value returned by calling
* <code>getMaximum(Calendar.YEAR)</code>.
* When rolling on the month or Calendar.MONTH field, other fields like
* date might conflict and, need to be changed. For instance,
* rolling the month on the date 01/31/96 will result in 02/29/96.
* When rolling on the hour-in-day or Calendar.HOUR_OF_DAY field, it will
* roll the hour value in the range between 0 and 23, which is zero-based.
大家注意一下如下注释,大概意思是用月份或者日期去进行回滚(即增加/减少天数)可能会引起冲突,并且直接给出冲突例子。
When rolling on the month or Calendar.MONTH field, other fields like date might conflict and,
need to be changed. For instance, rolling the month on the date 01/31/96 will result in 02/29/96.
那意思是api定义的时候就知道会出现这样的问题,但是并没有解决吗?那小幸就纳闷了,对于这种知道bug却不解决bug的函数,留着的用处是为何?
欢迎大家在留言区讨论哟~