MaterialDatePicker android 选择指定日期之前的日期而不是指定日期
MaterialDatePicker android selects previous to specified date instead of the specified date
当我创建 MaterialDatePicker
时,它会选择我指定日期的前一个日期,而不是指定日期:
您可以看到 EditText 有 2019 年 5 月 12 日,但 DatePicker 显示为 2019 年 5 月 11 日
openDatePicker 的代码是:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
String dateText = "May 12, 2019";
binding.etDate.setText(dateText);
try {
Date date = new SimpleDateFormat("MMM dd, yyyy").parse(dateText);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
binding.etDate.setTag(cal);
} catch (ParseException e) {
e.printStackTrace();
}
binding.etDate.setOnClickListener(v -> {
Calendar defaultCal = Calendar.getInstance();
if (binding.etDate.getTag() != null) {
defaultCal = (Calendar) binding.etDate.getTag();
}
openDatePicker(binding.etDate, defaultCal, createDatePickerConstraints(defaultCal, null, null));
});
}
private void openDatePicker(final EditText tv, Calendar defaultDate, CalendarConstraints constraints) {
try {
MaterialDatePicker.Builder<Long> builder = MaterialDatePicker.Builder.datePicker();
builder.setCalendarConstraints(constraints);
builder.setSelection(defaultDate.getTimeInMillis());
MaterialDatePicker<Long> datePicker = builder.build();
datePicker.addOnPositiveButtonClickListener(selection -> {
Calendar selectedCalObj = Calendar.getInstance();
selectedCalObj.setTimeInMillis((long) selection);
SimpleDateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy", Locale.ENGLISH);
dateFormat.setTimeZone(TimeZone.getDefault());
String date = dateFormat.format(selectedCalObj.getTime())
.replace("a.m.", "AM")
.replace("p.m.", "PM")
.replace("am", "AM")
.replace("pm", "PM");;
tv.setText(date);
tv.setTag(selectedCalObj);
});
datePicker.addOnNegativeButtonClickListener(view -> {
Log.d(TAG, "Cancelled");
});
datePicker.show(getSupportFragmentManager(), TAG);
} catch (Exception e) {
e.printStackTrace();
}
}
// helper function to give the constraints:
private CalendarConstraints createDatePickerConstraints(final Calendar entry, final Calendar start, final Calendar end) {
CalendarConstraints.Builder constraintsBuilder = new CalendarConstraints.Builder();
if (entry != null)
constraintsBuilder.setOpenAt(entry.getTimeInMillis());
if (start != null) {
constraintsBuilder.setStart(start.getTimeInMillis());
constraintsBuilder.setValidator(DateValidatorPointForward.from(start.getTimeInMillis()));
}
if (end != null) {
constraintsBuilder.setEnd(end.getTimeInMillis());
constraintsBuilder.setValidator(DateValidatorPointBackward.before(end.getTimeInMillis()));
}
return constraintsBuilder.build();
}
我知道的可能方法是通过将 onCreate
处的 EditText
binding.etDate.setTag
偏移到我所在的当前时区来解决(因为问题是 5 月 12 日) , 2019 0:00:00 这可能是 DatePicker 在打开时选择上一个日期的问题)但如果有更好的方法来执行此操作将会非常有帮助,因为这似乎是一个更常见的有用代码无处不在,这样我就可以将它作为一个库,并在我的主应用程序中将其作为库代码调用。
如有任何帮助,我们将不胜感激。
builder.setSelection(defaultDate.getTimeInMillis());
你必须像这样添加当前时间的偏移量
builder.setSelection(defaultDate.getTimeInMillis() + TimeZone.getDefault().getOffset(defaultDate.getTimeInMillis()));
因此,在经历了大量 GitHub 问题之后,我发现 MaterialDatePicker
仅针对 UTC 时间具有 getter 和 setter,因此抵消值不是一个好主意,因此传入当前时间作为 UTC,如:Link for converting current timezone to UTC
我的示例代码:
try {
SimpleDateFormat fromDate = new SimpleDateFromat("MMM dd, yyyy");
fromDate.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = fromDate.parse(inputDateString);
Calendar cal = Calendar.getInstance(Locale.getDefault());
cal.setTime(date);
binding.etDate.setTag(cal);
} catch (ParseException e) {
e.printStackTrace();
}
稍后我将使用 EditText
中的标签填充我的 CalendarConstraints
和 MaterialDatePicker
的 setSelection
。
希望对您有所帮助!
当我创建 MaterialDatePicker
时,它会选择我指定日期的前一个日期,而不是指定日期:
您可以看到 EditText 有 2019 年 5 月 12 日,但 DatePicker 显示为 2019 年 5 月 11 日
openDatePicker 的代码是:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
String dateText = "May 12, 2019";
binding.etDate.setText(dateText);
try {
Date date = new SimpleDateFormat("MMM dd, yyyy").parse(dateText);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
binding.etDate.setTag(cal);
} catch (ParseException e) {
e.printStackTrace();
}
binding.etDate.setOnClickListener(v -> {
Calendar defaultCal = Calendar.getInstance();
if (binding.etDate.getTag() != null) {
defaultCal = (Calendar) binding.etDate.getTag();
}
openDatePicker(binding.etDate, defaultCal, createDatePickerConstraints(defaultCal, null, null));
});
}
private void openDatePicker(final EditText tv, Calendar defaultDate, CalendarConstraints constraints) {
try {
MaterialDatePicker.Builder<Long> builder = MaterialDatePicker.Builder.datePicker();
builder.setCalendarConstraints(constraints);
builder.setSelection(defaultDate.getTimeInMillis());
MaterialDatePicker<Long> datePicker = builder.build();
datePicker.addOnPositiveButtonClickListener(selection -> {
Calendar selectedCalObj = Calendar.getInstance();
selectedCalObj.setTimeInMillis((long) selection);
SimpleDateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy", Locale.ENGLISH);
dateFormat.setTimeZone(TimeZone.getDefault());
String date = dateFormat.format(selectedCalObj.getTime())
.replace("a.m.", "AM")
.replace("p.m.", "PM")
.replace("am", "AM")
.replace("pm", "PM");;
tv.setText(date);
tv.setTag(selectedCalObj);
});
datePicker.addOnNegativeButtonClickListener(view -> {
Log.d(TAG, "Cancelled");
});
datePicker.show(getSupportFragmentManager(), TAG);
} catch (Exception e) {
e.printStackTrace();
}
}
// helper function to give the constraints:
private CalendarConstraints createDatePickerConstraints(final Calendar entry, final Calendar start, final Calendar end) {
CalendarConstraints.Builder constraintsBuilder = new CalendarConstraints.Builder();
if (entry != null)
constraintsBuilder.setOpenAt(entry.getTimeInMillis());
if (start != null) {
constraintsBuilder.setStart(start.getTimeInMillis());
constraintsBuilder.setValidator(DateValidatorPointForward.from(start.getTimeInMillis()));
}
if (end != null) {
constraintsBuilder.setEnd(end.getTimeInMillis());
constraintsBuilder.setValidator(DateValidatorPointBackward.before(end.getTimeInMillis()));
}
return constraintsBuilder.build();
}
我知道的可能方法是通过将 onCreate
处的 EditText
binding.etDate.setTag
偏移到我所在的当前时区来解决(因为问题是 5 月 12 日) , 2019 0:00:00 这可能是 DatePicker 在打开时选择上一个日期的问题)但如果有更好的方法来执行此操作将会非常有帮助,因为这似乎是一个更常见的有用代码无处不在,这样我就可以将它作为一个库,并在我的主应用程序中将其作为库代码调用。
如有任何帮助,我们将不胜感激。
builder.setSelection(defaultDate.getTimeInMillis());
你必须像这样添加当前时间的偏移量
builder.setSelection(defaultDate.getTimeInMillis() + TimeZone.getDefault().getOffset(defaultDate.getTimeInMillis()));
因此,在经历了大量 GitHub 问题之后,我发现 MaterialDatePicker
仅针对 UTC 时间具有 getter 和 setter,因此抵消值不是一个好主意,因此传入当前时间作为 UTC,如:Link for converting current timezone to UTC
我的示例代码:
try {
SimpleDateFormat fromDate = new SimpleDateFromat("MMM dd, yyyy");
fromDate.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = fromDate.parse(inputDateString);
Calendar cal = Calendar.getInstance(Locale.getDefault());
cal.setTime(date);
binding.etDate.setTag(cal);
} catch (ParseException e) {
e.printStackTrace();
}
稍后我将使用 EditText
中的标签填充我的 CalendarConstraints
和 MaterialDatePicker
的 setSelection
。
希望对您有所帮助!