• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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