Added getTimeString() which returns more than one element of a duration

(example: 3 hours, 12 minutes and 32 seconds).

Rewrote getTimeOrderString() to be iterative.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3312 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2005-01-27 00:46:44 +00:00
parent d2ea985abb
commit dc09c1214d
+86 -53
View File
@@ -1,5 +1,5 @@
// //
// $Id: TimeUtil.java,v 1.4 2004/08/27 02:20:36 mdb Exp $ // $Id$
// //
// Narya library - tools for developing networked games // Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved // Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
@@ -21,95 +21,128 @@
package com.threerings.util; package com.threerings.util;
import java.util.ArrayList;
/** /**
* Utility for times. * Utility for times.
*/ */
public class TimeUtil public class TimeUtil
{ {
/** Granularity constant. */ /** Time unit constant. */
public static final byte MILLISECOND = 0; public static final byte MILLISECOND = 0;
/** Granularity constant. */ /** Time unit constant. */
public static final byte SECOND = 1; public static final byte SECOND = 1;
/** Granularity constant. */ /** Time unit constant. */
public static final byte MINUTE = 2; public static final byte MINUTE = 2;
/** Granularity constant. */ /** Time unit constant. */
public static final byte HOUR = 3; public static final byte HOUR = 3;
/** Granularity constant. */ /** Time unit constant. */
public static final byte DAY = 4; public static final byte DAY = 4;
// TODO: Weeks?, months? // TODO: Weeks?, months?
protected static final byte MAX_UNIT = DAY;
/** /**
* Get a translatable string specifying the magnitude of the specified * Get a translatable string specifying the magnitude of the specified
* duration. Results will be between "1 second" and "X hours", with * duration. Results will be between "1 second" and "X hours", with
* all times rounded to the nearest unit. * all times rounded to the nearest unit. "0 units" will never be
* displayed, the minimum is 1.
*/ */
public static String getTimeOrderString ( public static String getTimeOrderString (long duration, byte minUnit)
long duration, byte minGranularity)
{ {
return getTimeOrderString(duration, minGranularity, Byte.MAX_VALUE); return getTimeOrderString(duration, minUnit, MAX_UNIT);
} }
/** /**
* Get a translatable string specifying the magnitude of the specified * Get a translatable string specifying the magnitude of the specified
* duration, with the units of time bounded between the minimum and * duration, with the units of time bounded between the minimum and
* maximum specified. * maximum specified. "0 units" will never be returned, the minimum is 1.
*/ */
public static String getTimeOrderString ( public static String getTimeOrderString (
long duration, byte minGranularity, byte maxGranularity) long duration, byte minUnit, byte maxUnit)
{ {
// enforce sanity // enforce sanity
minGranularity = (byte) Math.min(minGranularity, maxGranularity); minUnit = (byte) Math.min(minUnit, maxUnit);
maxUnit = (byte) Math.min(maxUnit, MAX_UNIT);
if (minGranularity == MILLISECOND) { for (byte uu = MILLISECOND; uu <= MAX_UNIT; uu++) {
if (duration < 2) { int quantity = getQuantityPerUnit(uu);
return "m.1millisecond"; if ((minUnit <= uu) && (duration < quantity || maxUnit == uu)) {
} else if (duration < 1000 || maxGranularity == MILLISECOND) { duration = Math.max(1, duration);
return MessageBundle.tcompose("m.milliseconds", return MessageBundle.tcompose(getTransKey(uu),
String.valueOf(duration)); String.valueOf(duration));
}
duration = Math.round(duration / quantity);
}
// will not happen, because eventually gg will be MAX_UNIT
Thread.dumpStack();
return null;
}
/**
* Get a translatable string specifying the duration, down to the
* minimum granularity.
*/
public static String getTimeString (long duration, byte minUnit)
{
// sanity
minUnit = (byte) Math.min(minUnit, MAX_UNIT);
duration = Math.abs(duration);
ArrayList list = new ArrayList();
int parts = 0; // how many parts are in the translation string?
for (byte uu = MILLISECOND; uu <= MAX_UNIT; uu++) {
int quantity = getQuantityPerUnit(uu);
if (minUnit <= uu) {
list.add(MessageBundle.tcompose(getTransKey(uu),
String.valueOf(duration % quantity)));
parts++;
}
duration /= quantity;
if (duration <= 0 && parts > 0) {
break;
} }
} }
int seconds = (int) Math.round(duration / 1000f); if (parts == 1) {
if (minGranularity <= SECOND) { return (String) list.get(0);
if (seconds < 2) {
return "m.1second";
} else if (seconds < 60 || maxGranularity == SECOND) {
return MessageBundle.tcompose("m.seconds",
String.valueOf(seconds));
}
}
int minutes = (int) Math.round(seconds / 60f);
if (minGranularity <= MINUTE) {
if (minutes < 2) {
return "m.1minute";
} else if (minutes < 60 || maxGranularity == MINUTE) {
return MessageBundle.tcompose("m.minutes",
String.valueOf(minutes));
}
}
int hours = (int) Math.round(minutes / 60f);
if (minGranularity <= HOUR) {
if (hours < 2) {
return "m.1hour";
} else if (hours < 24 || maxGranularity == HOUR) {
return MessageBundle.tcompose("m.hours", String.valueOf(hours));
}
}
int days = (int) Math.round(hours / 24f);
if (days < 2) {
return "m.1day";
} else { } else {
return MessageBundle.tcompose("m.days", String.valueOf(days)); return MessageBundle.compose("m.times_" + parts, list.toArray());
} }
}
// TODO: weeks? months? /**
* Internal method to get the quantity for the specified unit.
* (Not very OO)
*/
protected static int getQuantityPerUnit (byte unit)
{
switch (unit) {
case MILLISECOND: return 1000;
case SECOND: case MINUTE: return 60;
case HOUR: return 24;
default: return -1;
}
}
/**
* Internal method to get the translation key for the specified unit.
* (Not very OO)
*/
protected static String getTransKey (byte unit)
{
switch (unit) {
case MILLISECOND: return "m.millisecond";
case SECOND: return "m.second";
case MINUTE: return "m.minute";
case HOUR: return "m.hour";
case DAY: return "m.day";
default: return null;
}
} }
} }