1 /** 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 package com.android.healthconnect.controller.dataentries.formatters 15 16 import android.content.Context 17 import android.icu.text.MessageFormat 18 import com.android.healthconnect.controller.R 19 import java.text.NumberFormat 20 import java.time.Duration 21 22 /** Formatter for printing durations. */ 23 object DurationFormatter { 24 25 /** 26 * Formats the given duration in the format 'Xh Xm'. 27 * 28 * <p>Returns '0m' for durations less than a minute. Returns only the minute component for 29 * durations less than an hour. Returns only the hour component for durations with hours and 30 * zero minutes. 31 */ formatDurationShortnull32 fun formatDurationShort(context: Context, duration: Duration): String { 33 val hours: Long = duration.toHours() 34 val minutes: Long = duration.toMinutes() % 60 35 val integerFormat: NumberFormat = NumberFormat.getIntegerInstance() 36 val hourString: String = integerFormat.format(hours) 37 val minuteString: String = integerFormat.format(minutes) 38 if (hours > 0 && minutes > 0) { // Shows as: Nh Nm 39 return context.getString(R.string.hour_minute_duration_short, hourString, minuteString) 40 } 41 return if (hours > 0) { // Shows as: Nh 42 context.getString(R.string.hour_duration, hourString) 43 } else context.getString(R.string.minute_duration, minuteString) 44 // Shows as: Nm 45 } 46 47 /** 48 * Formats the given duration in the format 'X hours X minutes'. 49 * 50 * <p>Returns '0 minutes' for durations less than a minute. Returns only the minute component 51 * for durations less than an hour. Returns only the hour component for durations with hours and 52 * zero minutes. 53 */ formatDurationLongnull54 fun formatDurationLong(context: Context, duration: Duration): String { 55 val hours = duration.toHours() 56 val minutes = duration.toMinutes() % 60 57 val hourString: String = 58 MessageFormat.format( 59 context.getString(R.string.hour_duration_accessibility), mapOf("count" to hours)) 60 val minuteString: String = 61 MessageFormat.format( 62 context.getString(R.string.minute_duration_accessibility), 63 mapOf("count" to minutes)) 64 if (hours > 0 && minutes > 0) { // Shows as: N hour(s) N minute(s) 65 return context.getString( 66 R.string.hour_minute_duration_accessibility, hourString, minuteString) 67 } 68 return if (hours > 0) { // Shows as: N hour(s) 69 hourString 70 } else minuteString 71 // Shows as: N minute(s) 72 } 73 74 /** 75 * Formats the given duration in the format 'X days' or 'Y hours'. 76 * 77 * <p> Returns only the hour component for durations less than one day. Returns only the day 78 * component for durations with days. 79 */ formatDurationDaysOrHoursnull80 fun formatDurationDaysOrHours(context: Context, duration: Duration): String { 81 val days = duration.toDays() 82 val hours = duration.toHours() % 24 83 val dayString: String = 84 MessageFormat.format( 85 context.getString(R.string.day_duration_accessibility), mapOf("count" to days)) 86 val hourString: String = 87 MessageFormat.format( 88 context.getString(R.string.hour_duration_accessibility), mapOf("count" to hours)) 89 90 return if (days > 0) { // Shows as: X day(s) 91 dayString 92 } else { 93 hourString // Shows as: Y hour(s) 94 } 95 } 96 } 97