1

I have found a strange bug in my app, everytime i did a set on JDatePicker, it had added +1 month to the date I wanted it to be set on .. to be more specific, I have found out that the reason of this bug is that the LocalDate object months are not the same as Dates one ? I know that it sounds really strange, yet it was really the cause of the problem.

currentlyChanging.getDate() <- returns LocalDate

datePicker.getModel().setDate(currentlyChanging.getDate().getYear(),
                currentlyChanging.getDate().getMonth().getValue(),
                currentlyChanging.getDate().getDayOfMonth());

The code above will set the datepicker to 2020-11-15 instead of 2020-10-15 (so it adds +1 month). After further investigation I have noticed that when I convert this LocalDate to Date, everything starts to work fine, altho ... there is a problem ... IntelliJ is telling me that the getMonth method is deprecated, and I am not sure if its safe to use it if its just in this small use-case.

Date aaa = Helper.convertToDateViaSqlDate(currentlyChanging.getDate());

        datePicker.getModel().setDate(currentlyChanging.getDate().getYear(),
                aaa.getMonth(),
                currentlyChanging.getDate().getDayOfMonth());



---[helping method]---
public static Date convertToDateViaSqlDate(LocalDate dateToConvert) {
        return java.util.Date.from(dateToConvert.atStartOfDay()
                .atZone(ZoneId.systemDefault())
                .toInstant());
    }

I have searched around and the best way to get the Month I need is to use LocalDate, but that one is adding +1 month to my implementation and doing "- 1" seems to me like a ... how to say it .... not a good solution :D

Can someone please tell me why did this bug happen in a first place and at a same time, if there is a possiblity to fix it without using "getMonth" on Date, since this method is deprecated? Thanks in advance :)

StyleZ
  • 1,276
  • 3
  • 11
  • 27

1 Answers1

3

It is because java.util.Date considers January as month 0. Therefore, if you set 1 to datePicker.getModel(), it will be evaluated as February. This is one of the major design faults of java.util date-time API. On the other hand, java.time.LocalDate considers January as month 1 (which seems natural).

The solution to your problem is to deduct the month obtained from the LocalDate by 1 and then set it to datePicker.getModel() i.e.

datePicker.getModel().setDate(currentlyChanging.getDate().getYear(),
                currentlyChanging.getDate().getMonth().getValue() - 1,
                currentlyChanging.getDate().getDayOfMonth());

Given below is a quick demo of your problem:

import java.time.LocalDate;
import java.util.Calendar;

public class Main {
    public static void main(String[] args) {
        LocalDate localDate = LocalDate.of(2020, 1, 20);
        System.out.println(localDate);
        System.out.println(localDate.getMonth());
        System.out.println(localDate.getMonthValue());

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, localDate.getYear());
        calendar.set(calendar.MONTH, localDate.getMonthValue());
        calendar.set(Calendar.DAY_OF_MONTH, localDate.getDayOfMonth());
        System.out.println(calendar.getTime());
    }
}

Output:

2020-01-20
JANUARY
1
Thu Feb 20 21:14:28 GMT 2020

The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone (you just experienced one!). It is recommended to stop using them completely and switch to the modern date-time API.

Learn about the modern date-time API from Trail: Date Time.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110