From 2ec02a6bdcceb9e01464a67d8695bcdba5ceb6e1 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 25 Mar 2019 18:59:49 +0100 Subject: [PATCH] Apply rounding in StringUtil.formatDurationApproximate(); remove similar method from DateFormatUtil (IDEA-CR-45112) --- .../ShowFeatureUsageStatisticsDialog.java | 7 ++-- .../openapi/util/text/StringUtil.java | 33 +++++++++++++---- .../intellij/util/text/DateFormatUtil.java | 36 +------------------ .../intellij/util/text/StringUtilTest.java | 4 +++ 4 files changed, 35 insertions(+), 45 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsDialog.java b/platform/platform-impl/src/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsDialog.java index 03f254589904..bf190b58f80e 100644 --- a/platform/platform-impl/src/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsDialog.java +++ b/platform/platform-impl/src/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsDialog.java @@ -1,4 +1,4 @@ -// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.featureStatistics.actions; import com.intellij.CommonBundle; @@ -11,6 +11,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.TableViewSpeedSearch; import com.intellij.ui.table.TableView; @@ -138,10 +139,10 @@ public class ShowFeatureUsageStatisticsDialog extends DialogWrapper { final String uptimeS = FeatureStatisticsBundle.message("feature.statistics.application.uptime", ApplicationNamesInfo.getInstance().getFullProductName(), - DateFormatUtil.formatDuration(uptime)); + StringUtil.formatDurationApproximate(uptime)); final String idleTimeS = FeatureStatisticsBundle.message("feature.statistics.application.idle.time", - DateFormatUtil.formatDuration(idleTime)); + StringUtil.formatDurationApproximate(idleTime)); String labelText = uptimeS + ", " + idleTimeS; CompletionStatistics stats = ((FeatureUsageTrackerImpl)FeatureUsageTracker.getInstance()).getCompletionStatistics(); diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java index 2dd1652b1b81..801482e37ebe 100644 --- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java +++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java @@ -10,6 +10,8 @@ import com.intellij.openapi.util.TextRange; import com.intellij.util.*; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.*; +import gnu.trove.TIntArrayList; +import gnu.trove.TLongArrayList; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -1580,7 +1582,8 @@ public class StringUtil extends StringUtilRt { @NotNull @Contract(pure = true) private static String formatDuration(long duration, @NotNull String unitSeparator, int maxFragments) { - List fragments = new ArrayList<>(); + TLongArrayList unitValues = new TLongArrayList(); + TIntArrayList unitIndices = new TIntArrayList(); long count = duration; int i = 1; @@ -1589,21 +1592,37 @@ public class StringUtil extends StringUtilRt { if (count < multiplier) break; long remainder = count % multiplier; count /= multiplier; - if (remainder != 0 || fragments.size() > 0) { - fragments.add(0, remainder + unitSeparator + TIME_UNITS[i - 1]); + if (remainder != 0 || unitValues.size() > 0) { + unitValues.insert(0, remainder); + unitIndices.insert(0, i - 1); } else { remainder = Math.round(remainder * 100 / (double)multiplier); count += remainder / 100; } } + unitValues.insert(0, count); + unitIndices.insert(0, i - 1); - fragments.add(0, count + unitSeparator + TIME_UNITS[i - 1]); - if (fragments.size() > maxFragments) { - fragments = fragments.subList(0, maxFragments); + if (unitValues.size() > maxFragments) { + int lastUnitIndex = unitIndices.get(maxFragments - 1); + long lastMultiplier = TIME_MULTIPLIERS[lastUnitIndex]; + // Round up if needed + if (unitValues.get(maxFragments) > lastMultiplier / 2) { + long increment = lastMultiplier - unitValues.get(maxFragments); + for (int unit = lastUnitIndex - 1; unit > 0; unit--) { + increment *= TIME_MULTIPLIERS[unit]; + } + return formatDuration(duration + increment, unitSeparator, maxFragments); + } } - return join(fragments, " "); + StringBuilder result = new StringBuilder(); + for (i = 0; i < unitValues.size() && i < maxFragments; i++) { + if (i > 0) result.append(" "); + result.append(unitValues.get(i)).append(unitSeparator).append(TIME_UNITS[unitIndices.get(i)]); + } + return result.toString(); } /** diff --git a/platform/util/src/com/intellij/util/text/DateFormatUtil.java b/platform/util/src/com/intellij/util/text/DateFormatUtil.java index d6c03218c2d5..5140003ab82d 100644 --- a/platform/util/src/com/intellij/util/text/DateFormatUtil.java +++ b/platform/util/src/com/intellij/util/text/DateFormatUtil.java @@ -1,4 +1,4 @@ -// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.util.text; import com.intellij.CommonBundle; @@ -185,40 +185,6 @@ public class DateFormatUtil { return formatTime ? DATE_TIME_FORMAT.format(time) : DATE_FORMAT.format(time); } - @NotNull - public static String formatDuration(long delta) { - StringBuilder buf = new StringBuilder(); - for (int i = 0; i < DENOMINATORS.length; i++) { - long denominator = DENOMINATORS[i]; - int n = (int)(delta / denominator); - if (n != 0) { - buf.append(composeDurationMessage(PERIODS[i], n)); - buf.append(' '); - delta = delta % denominator; - } - } - - if (buf.length() == 0) return CommonBundle.message("date.format.less.than.a.minute"); - return buf.toString().trim(); - } - - private static String composeDurationMessage(final Period period, final int n) { - switch (period) { - case DAY: - return CommonBundle.message("date.format.n.days", n); - case MINUTE: - return CommonBundle.message("date.format.n.minutes", n); - case HOUR: - return CommonBundle.message("date.format.n.hours", n); - case MONTH: - return CommonBundle.message("date.format.n.months", n); - case WEEK: - return CommonBundle.message("date.format.n.weeks", n); - default: - return CommonBundle.message("date.format.n.years", n); - } - } - @NotNull public static String formatFrequency(long time) { return CommonBundle.message("date.frequency", formatBetweenDates(time, 0)); diff --git a/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java b/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java index c2d04183c1b5..8b1f7f8e6741 100644 --- a/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java +++ b/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java @@ -543,7 +543,11 @@ public class StringUtilTest { public void testFormatDurationApproximate() { assertEquals("2 m", StringUtil.formatDurationApproximate(120000)); assertEquals("2 m 3 s", StringUtil.formatDurationApproximate(123000)); + assertEquals("2 m 4 s", StringUtil.formatDurationApproximate(123789)); assertEquals("2 m 3 s", StringUtil.formatDurationApproximate(123456)); + assertEquals("1 h 1 m", StringUtil.formatDurationApproximate(3659009)); + assertEquals("2 h", StringUtil.formatDurationApproximate(7199000)); + assertEquals("1 d", StringUtil.formatDurationApproximate((23*60*60 + 59*60 + 59) * 1000L)); assertEquals("1 yr 1 mo", StringUtil.formatDurationApproximate(33786061001L)); }