解析日期字符串返回错误的月份 [英] Parse Date String Return Wrong Month

查看:74
本文介绍了解析日期字符串返回错误的月份的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试解析日期字符串,但总是得到错误的月份.这是我的代码.

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.

推荐答案

我从您的问题中得知,您正在使用JSR-310的反向端口,可能是Android版本ThreeTenABP.如果是这样,请全力以赴,并使用设计欠佳且过时的 Calendar Date 类.

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.

即使是在控件外部指定使用 Date 类,也必须远离其弃用的方法,包括 getYear()getMonth() getDate().收到 Date 并将其转换为 LocalDate 的第一件事时,您正在尝试做一件好事.从反向端口使用 DateTimeUtils 进行首次转换.

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.

但是,让我们从头开始.使用 LocalDate 设置日期选择器的初始日期.不要使用老式的 Calendar 类.我尚未编译代码,因此,如果有错字,请原谅.

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

当用户从日历/日期选择器中选择日期时,请勿将其存储为字符串.将其存储为 LocalDate 对象.这样可以避免以后进行任何解析,并且您的代码还显示您需要 LocalDate .显然,如果要向用户显示所选日期,请为此目的将日期格式化为字符串(仅).使用 DateTimeFormatter 进行格式化:

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");

现在我们去

                @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();

如果您无法控制从 list.getTglLahirAnak()获得的内容,则从 Date LocalDate 的转换是:

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.

就像过时的 Calendar 一样,不推荐使用的 Date.getMonth()也会计算从1月的0到12月的11的月份.因此,如果您选择5月的日期,则 list.getTglLahirAnak().getMonth()会返回5月的4.当您将其输入具有自然且合理的月份编号的 LocalDate 时,它便会为您提供4月.

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.

这篇关于解析日期字符串返回错误的月份的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆