Electrocode
Electrocode

Reputation: 317

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!

Upvotes: 8

Views: 2240

Answers (4)

praveen kumar
praveen kumar

Reputation: 134

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,

Upvotes: 3

Gilian Marques
Gilian Marques

Reputation: 547

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.

Upvotes: 5

Delly Fabian Lucas
Delly Fabian Lucas

Reputation: 79

try this code, add one day

 date.add(Calendar.DAY_OF_MONTH,1)

Upvotes: -1

Electrocode
Electrocode

Reputation: 317

I found the solution using calendar

picker.addOnPositiveButtonClickListener {
        val utc = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
        utc.timeInMillis = it
        //+1: The first month of the year in the Gregorian and Julian calendars is JANUARY which is 0
        val stringData = "${utc.get(Calendar.DAY_OF_MONTH)}/${utc.get(Calendar.MONTH)+1}/${utc.get(Calendar.YEAR)}"
        binding.edtBirthday.editText?.setText(stringData)
    }

Upvotes: 1

Related Questions