我有4个日历,分别是startCal,endCal,alerterCal和今天。今天只需获取当前日期/时间的Calendar.getInstance(),而其他3个则通过相同的方法使用Android的日期/时间选择器选择日期和时间。
startCal和endCal运行正常 if(startCal.after(endCal)){//处理错误}
但是,即使我故意在当前日期之前设置了hinterCal,alerterCal.before(今天)也不会返回true。
此外,在所有时间打印时,hinterCal没有任何时间(Time =?)和areFieldsSet = false,但是如果我第二次提交时间,则更新时间,尽管before()方法仍然没有工作!
除了else if if(reminderCal.before(today))以外,其他一切似乎都可以正常工作
public boolean validInput(){
if(startCal.after(endCal)){
//THIS WORKS
timeError.setText(getString(R.string.error_event_end_early));
isOk = false;
Log.e(TAG, "validInput: Event ends before it starts");
}
if(hasReminder.isChecked()){
if(reminderDate.getText().toString().matches("")) {
// THIS WORKS
reminderError.setText(R.string.error_no_reminder);
isOk = false;
Log.e(TAG, "validInput: No reminder set");
} else if (reminderCal.before(today)){
// THIS DOESN'T WORK. Why?
reminderError.setText(R.string.error_reminder_early);
isOk = false;
Log.e(TAG, "validInput: Reminder too early " + reminderCal.toString());
} else if(reminderCal.after(startCal)){
//THIS WORKS
reminderError.setText(R.string.error_reminder_late);
isOk = false;
Log.e(TAG, "validInput: Reminder too late");
}
return isOk;
}
Log.e(TAG, "Debugging: \n" +
"strCalandar: " + startCal.toString() + "\n" +
"endCalandar: " + endCal.toString() + "\n" +
"remCalandar: " + reminderCal.toString() + "\n" +
"todCalandar: " + today.toString() + "\n");
}
今天= Calander.getInstance();没有进一步的调整。其他日历通过这些方法获取日期/时间。
public void showDatePickerDialog(final EditText text, final Calendar cal){
Log.d(TAG, "showDatePickerDialog: Open");
DialogFragment datePicker = new DatePickerFragment();
((DatePickerFragment) datePicker).setOnDateChosenListener(new DatePickerFragment.OnDateChosenListener() {
@Override
public void onDateChosen(int year, int month, int day) {
text.setText(String.format("%02d/%02d/%04d", day, month, year));
cal.set(year, month, day);
}
});
datePicker.show(getSupportFragmentManager(), "DatePicker");
}
public void showTimePickerDialog(final EditText text, final Calendar cal){
Log.d(TAG, "showTimePickerDialog: Open");
DialogFragment timePicker = new TimePickerFragment();
((TimePickerFragment) timePicker).setOnTimeChosenListener(new TimePickerFragment.OnTimeChosenListener() {
@Override
public void onTimeChosen(int hour, int min) {
text.setText(String.format("%02d:%02d", hour, min));
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, min);
}
});
timePicker.show(getSupportFragmentManager(), "TimePicker");
}
Logcat中的输出:
strCalandar: java.util.GregorianCalendar[time=1566152201478,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=libcore.util.ZoneInfo[id="Europe/London",mRawOffset=0,mEarliestRawOffset=0,mUseDst=true,mDstSavings=3600000,transitions=242],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2019,MONTH=7,WEEK_OF_YEAR=33,WEEK_OF_MONTH=3,DAY_OF_MONTH=18,DAY_OF_YEAR=230,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=7,HOUR_OF_DAY=19,MINUTE=16,SECOND=41,MILLISECOND=478,ZONE_OFFSET=0,DST_OFFSET=3600000]
endCalandar: java.util.GregorianCalendar[time=1566152201478,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=libcore.util.ZoneInfo[id="Europe/London",mRawOffset=0,mEarliestRawOffset=0,mUseDst=true,mDstSavings=3600000,transitions=242],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2019,MONTH=7,WEEK_OF_YEAR=33,WEEK_OF_MONTH=3,DAY_OF_MONTH=18,DAY_OF_YEAR=230,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=7,HOUR_OF_DAY=19,MINUTE=16,SECOND=41,MILLISECOND=478,ZONE_OFFSET=0,DST_OFFSET=3600000]
remCalandar: java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=libcore.util.ZoneInfo[id="Europe/London",mRawOffset=0,mEarliestRawOffset=0,mUseDst=true,mDstSavings=3600000,transitions=242],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2019,MONTH=7,WEEK_OF_YEAR=31,WEEK_OF_MONTH=1,DAY_OF_MONTH=2,DAY_OF_YEAR=214,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=18,SECOND=41,MILLISECOND=478,ZONE_OFFSET=0,DST_OFFSET=3600000]
todCalandar: java.util.GregorianCalendar[time=1562775401478,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=libcore.util.ZoneInfo[id="Europe/London",mRawOffset=0,mEarliestRawOffset=0,mUseDst=true,mDstSavings=3600000,transitions=242],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2019,MONTH=6,WEEK_OF_YEAR=28,WEEK_OF_MONTH=2,DAY_OF_MONTH=10,DAY_OF_YEAR=191,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=16,SECOND=41,MILLISECOND=478,ZONE_OFFSET=0,DST_OFFSET=3600000]
如果提醒日期设置为当前日期之前,reminderCal.before(today)应该返回true
答案 0 :(得分:1)
他们试图在文档的这一部分中对此进行解释:
set(f, value)
将日历字段f
更改为value
。此外,它设置一个内部成员变量以指示 日历字段f
已更改。尽管日历字段f
为 立即更改,日历的时间值(以毫秒为单位)不是 重新计算直到下一次调用get()
,getTime()
, 制作了getTimeInMillis()
,add()
或roll()
。因此,多个 调用set()
不会触发多个不必要的计算。如 使用set()
和其他日历更改日历字段的结果 字段也可能会更改,具体取决于日历字段 字段值和日历系统。此外,get(f)
不会 必须返回通过调用set
方法后设置的值 日历字段已重新计算。具体取决于 具体的日历类。示例:考虑最初设置为1999年8月31日的GregorianCalendar。调用set(Calendar.MONTH,Calendar.SEPTEMBER)将日期设置为1999年9月31日。这是一个临时内部表示形式,它 如果随后调用getTime(),则解析为1999年10月1日。但是, 在调用getTime()之前调用set(Calendar.DAY_OF_MONTH,30) 将日期设置为1999年9月30日,因为没有重新计算 在set()本身之后。
因此,由于您分别调用cal.set(Calendar.HOUR_OF_DAY, hour);
和cal.set(Calendar.MINUTE, min);
,所以时间暂时不确定,这就是为什么从toString
打印问号的原因。
我无法重现before
和after
的举报行为,但是假设它们在get
或其中之一无法正常工作之前似乎是合理的。提到的getXxx
方法被调用。
这只是Calendar
类设计中非常令人困惑的方面之一。好的解决方案是切换到使用java.time, the modern Java date and time API。