I am using MaterialDatePicker in android studio for the user to be able to choose the date of birth, after selecting the date, the returned value is a long with the timestamp of the selected date (milliseconds since 01/01/1970). The problem is that the result obtained is slightly wrong, example: If the user selects the date 10/05/1998 (1st of October 1998), the date returned is one day before this, that is, the calendar returns 10/04 / 1998 (October 4, 1998).
My code:
Calendar calendar = Calendar.getInstance();
MaterialDatePicker.Builder<Long> builder =
MaterialDatePicker.Builder.datePicker();
MaterialDatePicker<Long> picker = builder.build();
picker.show(getChildFragmentManager(), picker.toString());
picker.addOnPositiveButtonClickListener(new MaterialPickerOnPositiveButtonClickListener<Long>() {
@Override
public void onPositiveButtonClick(Long selection) {
calendar.setTimeInMillis(selection);
SimpleDateFormat simpleDateFormat = new
SimpleDateFormat("dd/MM//yyyy",Locale.getDefault());
txtBirthDate.setText(simpleDateFormat.format(calendar.getTime()));
}
});
The calendar instance, now with timeInMillis has the selected date, only a day before. How can I fix this?
【Working solution in 2022】
It turns out that the MaterialDatePicker uses UTC time format, which means
it doesn't contain any Time Zone information, as the official states here.
That means we have to do some conversion work between UTC date-time and the zone date-time, the idea would be using the LocalDateTime api:
1. For showing correct date on picker, we need to convert zone date-time to UTC date-time:
Zone date-time (Long) -> zone LocalDateTime (object) -> UTC date-time (object)-> UTC date-time (Long).
2. For getting zone date-time from picker, we need to convert UTC date-time to zone date-time:
UTC date-time (Long) -> UTC LocalDateTime (object) -> zone date-time (object) -> zone date-time (Long)
Create Helper Extension Functions:
fun Long.toLocalDateTime() = LocalDateTime.ofInstant(Instant.ofEpochMilli(this), ZoneId.systemDefault())
fun Long.toUTCLocalDateTime() = LocalDateTime.ofInstant(Instant.ofEpochMilli(this), ZoneId.ofOffset("UTC", ZoneOffset.UTC))
Show MaterialDatePicker in Fragment:
private fun showDatePicker() {
val datePicker = MaterialDatePicker.Builder.datePicker().run {
setTitleText("Select Date")
setSelection(viewModel.dateLong.value.toLocalDateTime().atZone(ZoneId.ofOffset("UTC", ZoneOffset.UTC)).toInstant().toEpochMilli())
//setSelection(MaterialDatePicker.todayInUtcMilliseconds()) //show today's date
build()
}
datePicker.addOnPositiveButtonClickListener {
val dateLong = datePicker.selection!!.toUTCLocalDateTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()
viewModel.updateDateLong(dateLong)
}
datePicker.show(childFragmentManager, "")
}
Demo: https://youtu.be/9YWr3fgQ214
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With