Parse Date String Return Wrong Month

我的未来我决定 提交于 2021-01-29 10:15:44

问题


I try to parse date string but always get wrong month. Here's my code.

This is code to select date from calender

@OnClick(R.id.tedit_tgllahir_addnew) void showTimeDialog(){
        calendar = Calendar.getInstance();
        year = calendar.get(Calendar.YEAR);
        month = calendar.get(Calendar.MONTH);
        date = calendar.get(Calendar.DAY_OF_MONTH);
        DatePickerDialog datePickerDialog = new DatePickerDialog(AddDataForNewUserActivity.this,
                new DatePickerDialog.OnDateSetListener() {
                    @Override
                    public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                        etTgl.setText(String.format("%02d/%02d/%02d", year, month+1, dayOfMonth));
                    }

                }, year, month, date);

        datePickerDialog.show();
    }

and this is when i want to parse data

birth = LocalDate.of(list.getTglLahirAnak().getYear() + 1900, list.getTglLahirAnak().getMonth(), list.getTglLahirAnak().getDate());
                        int year =  Period.between(birth, LocalDate.now()).getYears();
                        int month = Period.between(birth, LocalDate.now()).getMonths();
                        int totalBulan = year * 12 + month;

Whenever I input date from the calender, it always shows the wrong month. For example I choose May but in the system read April. Thanks to all who are willing to help.


回答1:


I gather from your question that you are using the backport of JSR-310, probably the Android edition, ThreeTenABP. If so, go all-in on that and drop the use of the poorly designed and long outdated Calendar and Date classes.

Even if the use of the Date class is dictated from outside of your control, you must still stay away from its deprecated methods including getYear(), getMonth() and getDate(). You are trying the good thing when receiving a Date and converting it to a LocalDate first thing. Use DateTimeUtils from the backport for a first conversion.

But let’s take it from the top. Use LocalDate for setting the initial date of your date picker. Don’t use the old-fashioned Calendar class. I have not compiled the code, so please forgive if there’s a typo.

    LocalDate today = LocalDate.now(ZoneId.systemDefault());
    year = today.getYear();
    month = today.getMonthValue(); // naturally 1-based
    date = today.getDayOfMonth();
    DatePickerDialog datePickerDialog = new DatePickerDialog(AddDataForNewUserActivity.this,
            new DatePickerDialog.OnDateSetListener() {
                @Override
                public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                    // will return to this part later
                }

            }, year, month - 1, date); // Pass 0-based month

When the user selects a date from the calendar/date picker, don’t store it as a string. Store it as a LocalDate object. This saves you from doing any parsing later, and your code also shows that you need a LocalDate. Obviously if you want to show the selected date to the user, format the date into a string for that purpose (only). Use a DateTimeFormatter for formatting:

private static final DateTimeFormatter dateFormatter
        = DateTimeFormatter.ofPattern("yy/MM/dd");

Now we go:

                @Override
                public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                    // Store the selected date somewhere you can find it later
                    selectedLocalDate = LocalDate.of(year, month + 1, dayOfMonth);
                    // Display to the user
                    String formattedDate = selectedLocalDate.format(dateFormatter);
                    etTgl.setText(formattedDate);
                }

Now the calculation of age in months poses no problem anymore:

    birth = selectedLocalDate;
    long totalBulan = Period.between(birth, LocalDate.now(ZoneId.systemDefault()))
                           .toTotalMonths();

If you cannot control what you get from list.getTglLahirAnak(), the conversion from Date to LocalDate is:

    Date oldfashionedDate = list.getTglLahirAnak();
    birth = DateTimeUtils.toInstant(oldfashionedDate)
        .atZone(ZoneId.systemDefault())
        .toLocalDate();

Now the calculation of age proceeds as before.

What went wrong in your code?

Just like the outdated Calendar also the deprecated Date.getMonth() numbers the months from 0 for January through 11 for December. So if you pick a date in May, list.getTglLahirAnak().getMonth() returns 4 for May. When you feed this into a LocalDate with its natural and sensible month numbering, it gives you April.



来源:https://stackoverflow.com/questions/63065988/parse-date-string-return-wrong-month

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!