android - Expression of time difference

Keywords:android 


Question: 

Given a number of seconds/milliseconds, what is the best method to gracefully/cleanly express this time interval in the user's language, using the Android values/strings.xml API?

I am not asking for how to get the days/hours/minutes -- answers for that can be found in how to show milliseconds in days:hours:min:seconds and many other questions. For your information, my code for doing that:

int time1, time0; // given
int seconds, minutes, hours, days;
seconds = time1 - time0;
// TODO handle seconds <= 0
days = seconds / 86400;
hours = (seconds %= 86400) / 3600;
minutes = (seconds %= 3600) / 60;
seconds %= 60;

These are some methods I have brainstormed, but all have their disadvantages. What is the best method that doesn't have these problems?

Method 1: Using printf formats

strings.xml

<string name="format_time" formatted="false">
    %d day(s) %d hour(s) %d minute(s) %d second(s)
</string>

Java code

getString(R.string.format_time, days, hours, minutes, seconds);

Problem

As the (s)s would have inspired you, we don't like to see 0 day(s) 0 hour(s) 0 minute(s) 1 second(s). Neither do we like 1 day(s) 0 hour(s) 0 minute(s) 0 second(s), but just 1 day.

Method 2: Using terms per unit

strings.xml

<string-array name="time_units">
    <item>day(s)</item>
    <item>hour(s)</item>
    <item>minute(s)</item>
    <item>second(s)</item>
</string-array>
<string name="time_value_unit_separator">" "</string>
<string name="time_inter_unit_separator">", "</string>

Java code

String[] units = getResources().getStringArray(R.array.time_units);
int[] values = {days, hours, minutes, seconds};
assert units.length == values.length;
StringBuilder builder = new StringBuilder();
final String valueUnitSeparator = getString(R.string.time_value_unit_separator);
final String unitSeparator = getString(R.string.time_inter_unit_separator);
for(int i = 0; i < units.length; i++){
    if(values[i] > 0)
        builder.append(values[i])
                .append(valueUnitSeparator)
                .append(units[i])
                .append(unitSeparator);
}
return builder.substring(0, builder.length() - unitSeparator.length());

Problems

  1. According to Android Studio, it is discouraged that developers use string concatenation to build texts for user interface. I am unable to find official reasons behind it for reference.
  2. Maybe some languages prefer saying seconds 5 rather than 5 seconds?
  3. Maybe some languages prefer saying 30 seconds, 2 minutes rather than 2 minutes 30 seconds?



1 Answer: 

Regarding your first part with concatenation, there's no clean way to do it using the Android framework. The "official" reason would be it's slower to concat than it is to use formatting, but you're talking about milliseconds here. Worst case here, you're only going to update the text every one second so it's not a pain and nobody would notice.

There's a thing called Plurals which you can use to get different strings (i.e. "Hour" for 1 hour and "Hours" for >1 hour). So you could get a utility method like so and just use that:

public static String getHourString(Context ctx, int hours) {
   if (hours == 0) {
      return "";
   } else {
      return ctx.getResources().getQuantityString(R.plurals.hoursString, hours, hours);
   }
}

public static String getMinutesString(Context ctx, int mins) {
       if (mins == 0) {
          return "";
       } else {
          return ctx.getResources().getQuantityString(R.plurals.minutesString, mins, mins);
       }
    }

public static String getSecondsString(Context ctx, int secs) {
       if (secs == 0) {
          return "";
       } else {
          return ctx.getResources().getQuantityString(R.plurals.secondsString, secs, secs);
       }
    }

For time formatting, there is the Java time formatting and Joda-Time has some help with date locale as well.

Though that is for time and date formats. Your method (e.g. 1 minute, 1 second) isn't a standard as far as I know. For your method, you'll have to use Locale Directories and create a string for each language that you want to support. Although, since you have to manually concat the strings, this probably won't help you much.

 

More Articles


android - MediaRouter connect second time

I am using Android's MediaRouter / Presentation API (the support.v7 version).Everything works fine so far. The only thing that doesn't is:When I quit my activity (e.g.teardown & remove the callbacks), everything still works fine. However, when starting this activity (the previous mediarouter-act

r - Start with highlight mode enabled in ioslides

In ioslides presentation with Rmarkdown, there is an option to enable highlight mode in each slide by pressing h. Is there some way to make the highlight mode enabled by default and disable it by pressing h.

r - How can I incrementally build a plot in an ioslide presentation using Rmarkdown?

I'm trying to build a plot incrementally on one slide using Rmarkdown to create an ioslides (HTML) presentation. I've tried using {.build} but to no avail, and it seems there is no documentation on this in the Rmarkdown community. Does anyone know how to write this code in R?Here is a MWE where I tr


c# - XAML Layout- how to add a WebKitBrowser below buttons inside a <Grid>

I have the following XAML markup, which I am trying to use to display a WebKitBrowser below some buttons on the the GUI of my application:<DockPanel VerticalAlignment="Stretch" Height="Auto" HorizontalAlignment="Stretch" Width="Auto"> <Grid x:Name="browserGrid">

presentation - Replacing particular text in all sides of a ppt using python-pptx

I am new with python-pptx. But I am familiar with its basic working. I have searched a lot but I could not find a way to change a particular text by another text in all slides. That text may be in any text_frame of a slide. like all slides in a ppt have 'java' keyword, I want to change it by 'python

android - How to prevent AlertDialog using custom theme from appearing fullscreen?

I am using a custom style for my AlertDialogs, but it is making them appear fullscreen. I've searched around, but I could only seem to find people wanting to make it fullscreen... Here is my style <style name="MyDialog" parent="AlertDialog.AppCompat"> <item name="android:background">


objective c - iOS Project Structure for Presentation App

I'm gonna build presentation app, which will present a brandproduct.Presentation will have multiple slides (states) with commonbackground.In some slides I can go back to previous slideMy questions: 1. Do I have to use View Based Application? 2. For each state (slide) should I use separate UIViewCont

r - Embed javascript in Xaringan presentation

I have an interactive pooling question created using polleverywhere that would like to insert into my Xaringan rmarkdown presentation:<script src="https://www.polleverywhere.com/multiple_choice_polls/U43TXrlame7hw6J/web.js?height=250&results_count_format=percent&width=300"></script&

r - How to Make RStudio Presentation Self-contained?

I'm writing a presentation in R using RStudio. To create new presentation, I select "R Presentation" from the File => New File menu. RStudio creates new document. Here is the template:New Presentation========================================================author: date: First Slide===================

ios - Error: Attempt to present <UIImagePickerController: on <ViewController: while a presentation is in progress

Hey everyone and thank you for reading. I am making an app which you can take pictures and retreive pictures from the camera roll and display it on a view. The problem is that when I try to use the button which brings up the camera roll, I get the error "presentation is in progress" as above in the