String (long duration, @NotNull String unitSeparator, int maxFragments) { LongList unitValues = new LongArrayList(); IntList unitIndices = new IntArrayList(); long count = duration; int i = 1; for (; i < TIME_UNITS.length && count > 0; i++) { long multiplier = TIME_MULTIPLIERS[i]; if (count < multiplier) break; long remainder = count % multiplier; count /= multiplier; if (remainder != 0 || !unitValues.isEmpty()) { unitValues.add(0, remainder); unitIndices.add(0, i - 1); } } unitValues.add(0, count); unitIndices.add(0, i - 1); if (unitValues.size() > maxFragments) { int lastUnitIndex = unitIndices.getInt(maxFragments - 1); long lastMultiplier = TIME_MULTIPLIERS[lastUnitIndex]; // Round up if needed if (unitValues.getLong(maxFragments) > lastMultiplier / 2) { long increment = lastMultiplier - unitValues.getLong(maxFragments); for (int unit = lastUnitIndex - 1; unit > 0; unit--) { increment *= TIME_MULTIPLIERS[unit]; } return formatDuration(duration + increment, unitSeparator, maxFragments); } } StringBuilder result = new StringBuilder(); for (i = 0; i < unitValues.size() && i < maxFragments; i++) { if (i > 0) result.append(" "); result.append(unitValues.getLong(i)).append(unitSeparator).append(TIME_UNITS[unitIndices.getInt(i)]); } return result.toString(); }