How to get month from Material design Datepicker Android kotlin - android

I have a datepicker from material design, its opening well in the app.
Now how can i get for example the selected month from the datepicker.
Initialize the datepicker:
val datePicker = MaterialDatePicker.Builder.datePicker()
.setTitleText("Kies een datum")
.setSelection(MaterialDatePicker.todayInUtcMilliseconds())
.build()
On button hit the calendar opens:
fun pickDate() {
binding.DatepickerButton.setOnClickListener {
datePicker.show(activity?.supportFragmentManager!!, datePicker.toString())
}
}
so it shows, but i cannot get the data from it.

For Java 8, you can use Date/Time API
binding.DatepickerButton.addOnPositiveButtonClickListener {
var dateFormatter = DateTimeFormatter.ofPattern("MM", Locale.getDefault())
val month = dateFormatter.format(
Instant.ofEpochMilli(it)
.atZone(ZoneId.systemDefault()).toLocalDate()
)
}
Otherwise, you can use SimpleDateFormatter
binding.DatepickerButton.addOnPositiveButtonClickListener {
val calendar = Calendar.getInstance()
val simpleDateFormatter = SimpleDateFormat("MM", Locale.getDefault())
calendar.time = Date(it)
val month = simpleDateFormatter.format(calendar.time)
}

Try this click positive button click listener. after getting the date you can extract a month from it.
binding.DatepickerButton.addOnPositiveButtonClickListener {
val (startOfRange, endOfRange) = it // in case date range operation
val date = it // single select date
String dateString = DateFormat.format("dd/MM/yyyy", new Date(date)).toString();
}

Related

How can I add months Int to a choosen date on date picker in android Kotlin?

I have a working date picker in my app that replaces an EditText after a date selection. I want to add duration through a RadioGroup button that prints an Int to provoke an end date. How can I do that? I've spent the last two days without getting the result I'm looking to get.
Here is what I've got so far.
val datePicker = findViewById<DatePicker>(R.id.date_Picker)
val today = Calendar.getInstance()
datePicker.init(
today.get(Calendar.YEAR),
today.get(Calendar.MONTH),
today.get(Calendar.DAY_OF_MONTH
) { view, year, month, day ->
val month = month + 1
val startDay = ("$day-$month-$year")
binding.fechadeinicio.text = fechainicio
val duration = when (binding.duracion.checkedRadioButtonId) {
R.id.doce -> 12
R.id.veinticuatro -> 24
R.id.treintayseis -> 36
else -> 36
}
// val endDate = startDate.plusMonths(Duration.toLong())
// binding.endDate.text = endDate.toString()
}
Here is the closest one to the result I'm looking to get. Yet, I want to use the selected date val startDay, instead of val date = LocalDate.parse("2020-05-03"). When I replace it, the app crashes.
val date = LocalDate.parse("2020-05-03")
// Displaying date
println("Date : $date")
// Add 2 months to the date
val newDate = date.plusMonths(2)
println("New Date : $newDate")
Please, let me know how I can get the desired result?
Thanks.
I want to use the selected date that is val startDay instead of val date = LocalDate.parse("2020-05-03"). When I replace it, the app crashes.
val startDay = ("$day-$month-$year") here you've created date as dd-MM-yyyy, but by default LocalDate.parse uses DateTimeFormatter.ISO_LOCAL_DATE to parse a string, that parses a string of format yyyy-MM-dd to LocalDate. That's why it's crashing as your date is invalid according to that format.
You have to provide a DateTimeFormatter of pattern dd-MM-yyyy to parse your date.
You can do it like this
val startDay = ("$day-$month-$year")
val dateFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy")
binding.fechadeinicio.text = fechainicio
val duration = when (binding.duracion.checkedRadioButtonId) {
R.id.doce -> 12
R.id.veinticuatro -> 24
R.id.treintayseis -> 36
else -> 36
}
val startDate = LocalDate.parse(startDay, dateFormatter)
val endDate = startDate.plusMonths(duration.toLong()).format(dateFormatter)
binding.endDate.text = endDate
DatePicker returns year, month and day int values, now on creating date like val startDay = ("$day-$month-$year") would result in single digit for days and months less than 10, which would return 1 Jan 2020 as 1-1-2020 but date formatter is expecting it to be 01-01-2020.
To deal with this, we've to format int values before assigning it to the startDay, we can use format method of String to return 2 digits like this "%02d".format(intValue)
Change
val startDay = ("$day-$month-$year")
to
val startDay = "${"%02d".format(day)}-${"%02d".format(month)}-$year"
You can use LocalDate using of function.
Example here:
val date = LocalDate.of(year, month, day)
// Displaying date
println("Date : $date")
// Add 2 months to the date
val newDate = date.plusMonths(2)
println("New Date : $newDate")

Set date and get Date from Material Date Picker in Kotlin Android

I'm learning kotlin and at the moment I don't know much, I want to change a datepicker that I have for one of type Material, the problem is that I don't know how to pass the data to this new date picker.
This is the one I have at the moment:
fecha = view.findViewById(R.id.fecha)
fecha?.setOnClickListener {
fecha!!.error = null
val dateSetListener = DatePickerDialog(requireContext(), { _, year, monthOfYear, dayOfMonth ->
cal.set(Calendar.YEAR, year)
mYear = year
cal.set(Calendar.MONTH, monthOfYear)
mMonth = monthOfYear
cal.set(Calendar.DAY_OF_MONTH, dayOfMonth)
mDay = dayOfMonth
updateDateInView()
}, mYear, mMonth, mDay)
dateSetListener.datePicker.maxDate = System.currentTimeMillis()
dateSetListener.show()
}
fun updateDateInView() {
val myFormat = "dd/MM/yyyy"
val sdf = SimpleDateFormat(myFormat)
fecha?.setText(sdf.format(cal.time))
}
I want to make it like this but I don't know how to pass and save the values, could someone help me?
val datePicker = MaterialDatePicker.Builder.datePicker().build()
MaterialDatePicker accepts CalendarConstraints to open the date picker on a certain month. CalendarConstraints accepts timeInMilliseconds to open calendar on a particular month. MaterialDatePicker has an addOnPositiveButtonClickListener method whose lambda returns the time in milliseconds after the user makes a selection.
You can create MaterialDatePicker like this
val myFormat = "dd/MM/yyyy"
val formattedDate = "01/01/2000"
val sdf = SimpleDateFormat(myFormat)
val date = sdf.parse(formattedDate)
val timeInMillis = date.time
val constraintBuilder = CalendarConstraints.Builder().setOpenAt(
timeInMillis //pass time in milli seconds
).build()
val picker = MaterialDatePicker.Builder.datePicker()
.setTitleText("Select Date")
.setCalendarConstraints(constraintBuilder)
.build()
picker.addOnPositiveButtonClickListener {
val date = Date(it)
val formattedDate = sdf.format(date) // date selected by the user
}
// show picker using this
picker.show(requireActivity().supportFragmentManager, "materialDatePicker")
Instead of using SimpleDateFormatter, you should use LocalDateTime API provided in Java8
Using LocalDateTime API, you can do the same like this
val dateFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy", Locale.getDefault())
val formattedDate = "01/01/2000"
val timeInMillis = LocalDate.parse(formattedDate, dateFormatter)
.atStartOfDay(ZoneId.systemDefault())
.toInstant()
.toEpochMilli()
You can pass this timeInMillis to setOpenAt() method of CalendarConstraintSet.
To get the date after the user makes a selection
val timeInMillis = dateFormatter.format(
// it is the milliseconds received inside lambda of addOnPositiveButtonClickListener
Instant.ofEpochMilli(it)
.atZone(ZoneId.systemDefault()).toLocalDate()
)

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!
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)
}
try this code, add one day
date.add(Calendar.DAY_OF_MONTH,1)

DatePicker dialog may showing improper date in kotlin

Below is the function I am using to diplay date picker dialog in android.
private fun openPurchaseDatePickerDialog(
yearToDisplay: Int,
monthToDisplay: Int,
dayToDisplay: Int
) {
try {
activity?.let { KeyboardUtils.hideKeyboard(it) }
val calendar = Calendar.getInstance()
val dialog = DatePickerDialog(activity, { _, year, month, day_of_month ->
calendar[Calendar.YEAR] = year
calendar[Calendar.MONTH] = month
calendar[Calendar.DAY_OF_MONTH] = day_of_month
val myFormat = "" + DateUtils.OverAllAppDateDisplayFormat
val sdf = SimpleDateFormat(myFormat, Locale.getDefault())
edtPurchaseDate.setText(sdf.format(calendar.time).toString())
spIntendedUse.isFocusable = true
}, yearToDisplay, monthToDisplay, dayToDisplay)
dialog.updateDate(yearToDisplay,monthToDisplay,dayToDisplay)
dialog.datePicker.maxDate = calendar.timeInMillis
dialog.show()
} catch (e: Exception) {
e.printStackTrace()
}
As above you can check that there are three arguments passed in this function.
I have to show the specific date in DatePicker dialog show I have passed this three parameters.
Means If User selected the date first time the default values will be set or the current date will be set.
If edittext has already a text selected and not empty am doing as below :
if (edtPurchaseDate.text.toString().isNullOrEmpty()) {
val calendar = Calendar.getInstance()
openPurchaseDatePickerDialog(
calendar[Calendar.YEAR],
calendar[Calendar.MONTH],
calendar[Calendar.DAY_OF_MONTH]
)
} else {
var dateArr = edtPurchaseDate.text.toString().split("-")
openPurchaseDatePickerDialog(
dateArr[2].toInt(),
dateArr[1].toInt(),
dateArr[0].toInt()
)
}
But Still when the date picker dialogs opens its displaying the selected as as today instead of custom.
What might be the issue?
You can see I have also tried with updateDate() function as below :
dialog.updateDate(yearToDisplay,monthToDisplay,dayToDisplay)
Thanks.
Not completely sure about the updateDate method issue here . But to fix this you can use same Calendar object during initialization it should work fine .
i have modified your method a bit .
private fun openPurchaseDatePickerDialog(date: String) {
try {
val calendar = Calendar.getInstance()
if (date.isNotBlank()) {
try {
calendar.time = SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()).parse(date)!!
}catch (e:ParseException){
}
}
val dialog = DatePickerDialog(this, { _, year, month, day_of_month ->
calendar[Calendar.YEAR] = year
calendar[Calendar.MONTH] = month
calendar[Calendar.DAY_OF_MONTH] = day_of_month
val myFormat = "dd-MM-yyyy"
val sdf = SimpleDateFormat(myFormat, Locale.getDefault())
edtPurchaseDate.setText(sdf.format(calendar.time).toString())
}, calendar[Calendar.YEAR], calendar[Calendar.MONTH], calendar[Calendar.DAY_OF_MONTH])
dialog.datePicker.maxDate = System.currentTimeMillis()
dialog.show()
} catch (e: Exception) {
e.printStackTrace()
}
}
Now when you call it you just call it with a value you do mnot have to split String.
openPurchaseDatePickerDialog(edtPurchaseDate.text.toString())

How to display different date/time format in textview using hr, day and calender

I am trying to work on displaying dates and I am experiencing a challenge. So I have this one textview in my adapter class and I want the time displayed to be in 3 different format, Say for instance when its past 24hrs say date e.g Saturday if its very old just display date 02/9/2021 and if a day has not ended just display time 12:00am my problem is how do I achieve this on Android using Kotlin? here is a sample image I got
It's simple just get difference between now and your date and use SimpleDateFormat to formate date
fun getDate(date:Long){
val nowCal = Calendar.getInstance()
val dateCal = Calendar.getInstance().apply {
//just for test, replace with your date timestamp
timeInMillis += TimeUnit.DAYS.toMillis(9)
}
val nowDay = TimeUnit.MILLISECONDS.toDays(nowCal.timeInMillis)
val dateDay = TimeUnit.MILLISECONDS.toDays(dateCal.timeInMillis)
when {
(dateDay - nowDay) <= 1L -> {
val formatter = SimpleDateFormat("hh:mm a")
val dateStr = formatter.format(dateCal.time)
println(dateStr)
}
(dateDay - nowDay) <= 6L -> {
val dateStr = dateCal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.ENGLISH)
println(dateStr)
}
else ->{
val formatter = SimpleDateFormat("M/d/yy")
val dateStr = formatter.format(dateCal.time)
println(dateStr)
}
}
}

Categories

Resources