I am storing time in Milliseconds using a Material Time Picker Dialog. The problem is if I choose a time instance which is like a single valued hour (between 1-9) or single valued minute(1-9) then I am able to get the value in milliseconds. But if I set the bigger values of time I get an exception java.lang.ArrayIndexOutOfBoundsException: length=17; index=20
What am I doing wrong here? Or what is the better approach to do this.
Log for reference :
My Code (Not the complete code but what is required for this question) :
//Time Picker
var picker: MaterialTimePicker = MaterialTimePicker()
//Long values to be stored in database
val timeStart: Long = 0
//Setting Start Time
binding.timeStart.setOnClickListener {
openTimePicker()
picker.addOnPositiveButtonClickListener {
val h = picker.hour
val m = picker.minute
binding.timeStart.text = "$h:$m"
Timber.d("Start Time - h: $h m: $m")
try {
val calendar = Calendar.getInstance()
calendar.get(h)
calendar.get(m)
val timeInMilliSeconds = calendar.timeInMillis
Timber.d("$timeInMilliSeconds")
} catch (e: Exception) {
Timber.d("$e")
}
}
}
private fun openTimePicker() {
val isSystem24Hour = is24HourFormat(requireContext())
val clockFormat = if (isSystem24Hour) TimeFormat.CLOCK_24H else TimeFormat.CLOCK_12H
picker = MaterialTimePicker.Builder()
.setTimeFormat(clockFormat)
.setHour(12)
.setMinute(10)
.setTitleText("Set Start Time")
.build()
picker.show(childFragmentManager, "TAG")
}
CodePudding user response:
It's happening here:
val h = picker.hour
val m = picker.minute
binding.timeStart.text = "$h:$m"
Timber.d("Start Time - h: $h m: $m")
try {
val calendar = Calendar.getInstance()
calendar.get(h)
calendar.get(m)
val timeInMilliSeconds = calendar.timeInMillis
Timber.d("$timeInMilliSeconds")
}
Specifically when you call calendar.get()
public int get (int field)
Returns the value of the given calendar field Throws
ArrayIndexOutOfBoundsException
if the specified field is out of range(field < 0 || field >= FIELD_COUNT)
public static final int FIELD_COUNT
The number of distinct fields recognized by
get
andset
. Field numbers range from0..FIELD_COUNT-1
Constant Value: 17
That's why your exception is complaining that the array has 17 items and you're trying to access index 20, because you're passing values representing hours and minutes instead of field constants.
I'm not sure what you want to do exactly, but look at the set
or add
methods in the Calendar
class, if you want to specify an exact time or you want to add x hours and y minutes to the current time. You'll need to use the field constants to specify which value you're changing, e.g. HOUR_OF_DAY
CodePudding user response:
A better approach to get the time in milliseconds using TimeUnit
instead of Calendar. I used TimeUnit.HOURS.toMillis(myHours)
and TimeUnit.MINUTES.toMillis(myMinutes)
to get my hours and minutes in milliseconds and then add them to get the time in milliseconds.
Code :
binding.timeStart.setOnClickListener {
openTimePicker()
picker.addOnPositiveButtonClickListener {
val h = picker.hour
val m = picker.minute
binding.timeStart.text = "$h:$m"
Timber.d("Start Time - $h: $m")
try {
val hour = TimeUnit.HOURS.toMillis(h.toLong())
val minute = TimeUnit.MINUTES.toMillis(m.toLong())
val totalTime = hour minute
Timber.d("Hour - $hour, Minute - $minute, Total = $totalTime")
timeStart = totalTime
} catch (e: Exception) {
Timber.d("$e")
}
}
}
private fun openTimePicker() {
picker = MaterialTimePicker.Builder()
.setTimeFormat(TimeFormat.CLOCK_12H)
.setHour(12)
.setMinute(10)
.setTitleText("Set Start Time")
.build()
picker.show(childFragmentManager, "TAG")
}