简体   繁体   中英

Index out bounds exception when storing time in milliseconds [Android]

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 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")
    }

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 and set . Field numbers range from 0..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, eg HOUR_OF_DAY

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")
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM