Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wrong day in Android Material DatePicker

i'm trying to get te selected date from DatePicker but always i have one day less than the selected

For example, if I select 14/2/2022 i obtain 13/2/2022 and if I select 8/10/2018 i obtain 7/10/2018

This is my code:

private fun DatePickerSelected() {
    val picker = MaterialDatePicker.Builder.datePicker()
        .setTitleText("Select date of birth")
        .setSelection(MaterialDatePicker.todayInUtcMilliseconds())
        .build()

    picker.addOnPositiveButtonClickListener {
        val date = Date(picker.selection!!)
        Log.d("Date",date.toString())
        val dateString = SimpleDateFormat("dd/MM/yyyy").format(date)
        binding.edtBirthday.editText?.setText(dateString)
    }

    picker.show(requireActivity().supportFragmentManager, "BirthdayPicker")
}

Which is the problem? Thanks!

like image 638
Electrocode Avatar asked Apr 28 '26 01:04

Electrocode


2 Answers

It turns out that the result from a call to picker is a timestamp in UTC timezone, all you gotta do is to convert it to yout local timezone.

Below is the logic to show a DialogPicker with a listener that converts the result from UTC to the device´s time zone:

  // create the dialog picker
    val picker = MaterialDatePicker.Builder
        .datePicker()
        .setSelection(initialDate)// initial date can be a date on local timezone
        .setTitleText("")
        .build()

    picker.addOnPositiveButtonClickListener {
        // create an object with a matching timezone
        val utcDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(it), ZoneOffset.UTC)
        // create an object converting from UTC to the device´s timezone
        val myTimeZoneDate = ZonedDateTime.of(utcDate, ZoneId.systemDefault())
        // get the long timestamp to use as you want
        val myTimeZoneDateLong = myTimeZoneDate.toInstant().toEpochMilli()

    }
    
    // show picker
    picker.show(parentFragmentManager, "tag")

Remember: You should always handle Date as time zoneless what includes store it in a database, using it to synchronize data or make comparations. The only exception is when you show it to user in this case obviously it should be converted to local timezone. Not doing this will cause really big problems if your users use your app with diferent timezones.

like image 169
Gilian Marques Avatar answered Apr 29 '26 21:04

Gilian Marques


I have the same issue in jetpack compose, material date picker ,

Root cause These date pickers return epoch time - AKA UTC (universal Coordinated Time) e.g : if you click a date of 25 jan 2024 , these Api's will return epoch date and time of **25 jan 2024 00:00:00 AM ,

but problem arrives when you directly consume the data, because ,users aren't use UTC time,

FIX convert the UTC -> LocalTimeZone before consuming data in api

fun epochToLocalTimeZoneConvertor(epoch: Long): Long{
val epochCalendar = Calendar.getInstance()
epochCalendar.timeZone = TimeZone.getTimeZone("UTC")
epochCalendar.timeInMillis = epoch
val converterCalendar = Calendar.getInstance()
converterCalendar.set(
    epochCalendar.get(Calendar.YEAR),
    epochCalendar.get(Calendar.MONTH),
    epochCalendar.get(Calendar.DATE),
    epochCalendar.get(Calendar.HOUR_OF_DAY),
    epochCalendar.get(Calendar.MINUTE),
)
converterCalendar.timeZone = TimeZone.getDefault()
return converterCalendar.timeInMillis }

this solution is written in Kotlin,

like image 32
praveen kumar Avatar answered Apr 29 '26 21:04

praveen kumar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!