1 /* 2 * Copyright (C) 2016 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 androidx.annotation.StringRes; 21 22 import com.android.deskclock.R; 23 import com.android.deskclock.Utils; 24 25 import static android.text.format.DateUtils.HOUR_IN_MILLIS; 26 import static android.text.format.DateUtils.MINUTE_IN_MILLIS; 27 import static android.text.format.DateUtils.SECOND_IN_MILLIS; 28 29 public class TimerStringFormatter { 30 31 /** 32 * Format "7 hours 52 minutes 14 seconds remaining" 33 */ formatTimeRemaining(Context context, long remainingTime, boolean shouldShowSeconds)34 public static String formatTimeRemaining(Context context, long remainingTime, 35 boolean shouldShowSeconds) { 36 int roundedHours = (int) (remainingTime / HOUR_IN_MILLIS); 37 int roundedMinutes = (int) (remainingTime / MINUTE_IN_MILLIS % 60); 38 int roundedSeconds = (int) (remainingTime / SECOND_IN_MILLIS % 60); 39 40 final int seconds; 41 final int minutes; 42 final int hours; 43 if ((remainingTime % SECOND_IN_MILLIS != 0) && shouldShowSeconds) { 44 // Add 1 because there's a partial second. 45 roundedSeconds += 1; 46 if (roundedSeconds == 60) { 47 // Wind back and fix the hours and minutes as needed. 48 seconds = 0; 49 roundedMinutes += 1; 50 if (roundedMinutes == 60) { 51 minutes = 0; 52 roundedHours += 1; 53 hours = roundedHours; 54 } else { 55 minutes = roundedMinutes; 56 hours = roundedHours; 57 } 58 } else { 59 seconds = roundedSeconds; 60 minutes = roundedMinutes; 61 hours = roundedHours; 62 } 63 } else { 64 // Already perfect precision, or we don't want to consider seconds at all. 65 seconds = roundedSeconds; 66 minutes = roundedMinutes; 67 hours = roundedHours; 68 } 69 70 final String minSeq = Utils.getNumberFormattedQuantityString(context, R.plurals.minutes, 71 minutes); 72 final String hourSeq = Utils.getNumberFormattedQuantityString(context, R.plurals.hours, 73 hours); 74 final String secSeq = Utils.getNumberFormattedQuantityString(context, R.plurals.seconds, 75 seconds); 76 77 // The verb "remaining" may have to change tense for singular subjects in some languages. 78 final String remainingSuffix = context.getString((minutes > 1 || hours > 1 || seconds > 1) 79 ? R.string.timer_remaining_multiple 80 : R.string.timer_remaining_single); 81 82 final boolean showHours = hours > 0; 83 final boolean showMinutes = minutes > 0; 84 final boolean showSeconds = (seconds > 0) && shouldShowSeconds; 85 86 int formatStringId = -1; 87 if (showHours) { 88 if (showMinutes) { 89 if (showSeconds) { 90 formatStringId = R.string.timer_notifications_hours_minutes_seconds; 91 } else { 92 formatStringId = R.string.timer_notifications_hours_minutes; 93 } 94 } else if (showSeconds) { 95 formatStringId = R.string.timer_notifications_hours_seconds; 96 } else { 97 formatStringId = R.string.timer_notifications_hours; 98 } 99 } else if (showMinutes) { 100 if (showSeconds) { 101 formatStringId = R.string.timer_notifications_minutes_seconds; 102 } else { 103 formatStringId = R.string.timer_notifications_minutes; 104 } 105 } else if (showSeconds) { 106 formatStringId = R.string.timer_notifications_seconds; 107 } else if (!shouldShowSeconds) { 108 formatStringId = R.string.timer_notifications_less_min; 109 } 110 111 if (formatStringId == -1) { 112 return null; 113 } 114 return String.format(context.getString(formatStringId), hourSeq, minSeq, remainingSuffix, 115 secSeq); 116 } 117 formatString(Context context, @StringRes int stringResId, long currentTime, boolean shouldShowSeconds)118 public static String formatString(Context context, @StringRes int stringResId, long currentTime, 119 boolean shouldShowSeconds) { 120 return String.format(context.getString(stringResId), 121 formatTimeRemaining(context, currentTime, shouldShowSeconds)); 122 } 123 } 124