我尝试解析日期字符串,但总是得到错误的月份。这是我的代码。
这是从日历中选择日期的代码
@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();
}
这是我要解析数据的时候
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;
每当我输入日历中的日期时,它总是显示错误的月份。例如,我选择“五月”,但在系统中读取“四月”。感谢所有愿意提供帮助的人。
答案 0 :(得分:1)
我从您的问题中得知您正在使用JSR-310的反向端口,可能是Android版本ThreeTenABP。如果是这样,请全力以赴,并放弃使用设计不良且过时的Calendar
和Date
类。
即使Date
类的使用是出于控制之外的,您仍必须远离其弃用的方法,包括getYear()
,getMonth()
和getDate()
。收到Date
并将其转换为LocalDate
的第一件事时,您正在尝试做一件好事。从反向端口使用DateTimeUtils
进行第一次转换。
但是,让我们从头开始。使用LocalDate
设置日期选择器的初始日期。不要使用老式的Calendar
类。我尚未编译代码,因此,如果有错字,请原谅。
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
进行格式化:
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);
}
现在以月为单位的年龄计算不再是问题:
birth = selectedLocalDate;
long totalBulan = Period.between(birth, LocalDate.now(ZoneId.systemDefault()))
.toTotalMonths();
如果您无法控制从list.getTglLahirAnak()
获得的收益,则从Date
到LocalDate
的转换是:
Date oldfashionedDate = list.getTglLahirAnak();
birth = DateTimeUtils.toInstant(oldfashionedDate)
.atZone(ZoneId.systemDefault())
.toLocalDate();
现在年龄的计算与以前一样。
就像过时的Calendar
一样,过时的Date.getMonth()
也将数字从1月的0到12月的11月份。因此,如果您选择5月的日期,则list.getTglLahirAnak().getMonth()
将返回5的4。当您使用自然且合理的月份编号将其输入到LocalDate
中时,它便为您提供4月。