1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.deskclock.data 18 19 import android.content.Context 20 import android.text.format.DateUtils.HOUR_IN_MILLIS 21 import android.text.format.DateUtils.MINUTE_IN_MILLIS 22 import android.text.format.DateUtils.SECOND_IN_MILLIS 23 import androidx.annotation.StringRes 24 25 import com.android.deskclock.R 26 import com.android.deskclock.Utils 27 28 object TimerStringFormatter { 29 /** 30 * Format "7 hours 52 minutes 14 seconds remaining" 31 */ 32 @JvmStatic formatTimeRemainingnull33 fun formatTimeRemaining( 34 context: Context, 35 remainingTime: Long, 36 shouldShowSeconds: Boolean 37 ): String? { 38 var roundedHours = (remainingTime / HOUR_IN_MILLIS).toInt() 39 var roundedMinutes = (remainingTime / MINUTE_IN_MILLIS % 60).toInt() 40 var roundedSeconds = (remainingTime / SECOND_IN_MILLIS % 60).toInt() 41 42 val seconds: Int 43 val minutes: Int 44 val hours: Int 45 if (remainingTime % SECOND_IN_MILLIS != 0L && shouldShowSeconds) { 46 // Add 1 because there's a partial second. 47 roundedSeconds += 1 48 if (roundedSeconds == 60) { 49 // Wind back and fix the hours and minutes as needed. 50 seconds = 0 51 roundedMinutes += 1 52 if (roundedMinutes == 60) { 53 minutes = 0 54 roundedHours += 1 55 hours = roundedHours 56 } else { 57 minutes = roundedMinutes 58 hours = roundedHours 59 } 60 } else { 61 seconds = roundedSeconds 62 minutes = roundedMinutes 63 hours = roundedHours 64 } 65 } else { 66 // Already perfect precision, or we don't want to consider seconds at all. 67 seconds = roundedSeconds 68 minutes = roundedMinutes 69 hours = roundedHours 70 } 71 72 val minSeq = Utils.getNumberFormattedQuantityString(context, R.plurals.minutes, minutes) 73 val hourSeq = Utils.getNumberFormattedQuantityString(context, R.plurals.hours, hours) 74 val secSeq = Utils.getNumberFormattedQuantityString(context, R.plurals.seconds, seconds) 75 76 // The verb "remaining" may have to change tense for singular subjects in some languages. 77 val remainingSuffix: String = 78 context.getString(if (minutes > 1 || hours > 1 || seconds > 1) { 79 R.string.timer_remaining_multiple 80 } else { 81 R.string.timer_remaining_single 82 }) 83 84 val showHours = hours > 0 85 val showMinutes = minutes > 0 86 val showSeconds = seconds > 0 && shouldShowSeconds 87 88 var formatStringId = -1 89 if (showHours) { 90 formatStringId = if (showMinutes) { 91 if (showSeconds) { 92 R.string.timer_notifications_hours_minutes_seconds 93 } else { 94 R.string.timer_notifications_hours_minutes 95 } 96 } else if (showSeconds) { 97 R.string.timer_notifications_hours_seconds 98 } else { 99 R.string.timer_notifications_hours 100 } 101 } else if (showMinutes) { 102 formatStringId = if (showSeconds) { 103 R.string.timer_notifications_minutes_seconds 104 } else { 105 R.string.timer_notifications_minutes 106 } 107 } else if (showSeconds) { 108 formatStringId = R.string.timer_notifications_seconds 109 } else if (!shouldShowSeconds) { 110 formatStringId = R.string.timer_notifications_less_min 111 } 112 113 return if (formatStringId == -1) { 114 null 115 } else { 116 String.format(context.getString(formatStringId), hourSeq, minSeq, 117 remainingSuffix, secSeq) 118 } 119 } 120 121 @JvmStatic formatStringnull122 fun formatString( 123 context: Context, 124 @StringRes stringResId: Int, 125 currentTime: Long, 126 shouldShowSeconds: Boolean 127 ): String { 128 return String.format(context.getString(stringResId), 129 formatTimeRemaining(context, currentTime, shouldShowSeconds)) 130 } 131 }