I am comparing the start Date of a treatement to its End to check if it lasts more than 6 months. If the period doesn't include the month of February all is good but if I compare the 1st of January to the 30th of June, it throws my Exception. To compare both periods I add 6 months to the start Date and compare the result to the end Date like so:
Date start = new Date(2017,1,1);
Date end = new Date(2017,6,30);
Calendar startOfTreatment = new Calendar.getInstance();
startOfTreatment.setTime(start);
Calendar endOfTreatment = new Calendar.getInstance();
endOfTreatment.setTime(end);
startOfTreatment.add(Calendar.MONTH, 6);
if (startOfTreatment.compareTo(endOfTreatment) > 0) {
throw new InfinishedTreatmentException(startOfTreatment,endOfTreatment);
}
How can I fix this?
The
Date
constructors (like the one you're using:new Date(2017,1,1)
) are not only deprecated (so you should avoid them) but also misleading, because years are indexed at 1900 (so 2017 becomes 3917) and months are zero-indexed (the values are in the range zero (January) to 11 (December)). So this doesn't behave as you think:When you add 6 months to
start
, it becomes August 1st, which is afterend
.To create January 1st and June 30th you must use
month - 1
and to have the year 2017 you must use 117 (2017 - 1900):Even though,
start
plus 6 months will be July 1st, which still is afterend
(so your code will throw the exception).The old classes (
Date
,Calendar
andSimpleDateFormat
) have lots of problems and design issues, and they're being replaced by the new APIs.In Java <= 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes.
This new API has lots of new date and time types to deal with different situations. As we're dealing only with dates (day/month/year), we can use a
org.threeten.bp.LocalDate
: