From fbe20767653f7574c6d62361b6724e9a3adeed0d Mon Sep 17 00:00:00 2001 From: Nikolai Fedorovskikh Date: Tue, 10 Jan 2023 05:28:28 +0400 Subject: [PATCH] Several optimizations in the method `DurationFormatUtils#formatDurationWords` --- .../lang3/time/DurationFormatUtils.java | 59 ++++++++++++------- .../lang3/time/DurationFormatUtilsTest.java | 8 +++ 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/apache/commons/lang3/time/DurationFormatUtils.java b/src/main/java/org/apache/commons/lang3/time/DurationFormatUtils.java index d1b04656843..f30d85f4f36 100644 --- a/src/main/java/org/apache/commons/lang3/time/DurationFormatUtils.java +++ b/src/main/java/org/apache/commons/lang3/time/DurationFormatUtils.java @@ -179,48 +179,63 @@ public static String formatDurationWords( // there are a series of tweaks and special cases that require // trickery to replicate. String duration = formatDuration(durationMillis, "d' days 'H' hours 'm' minutes 's' seconds'"); + boolean hasDays = true; + boolean hasHours = true; + boolean hasMinutes = true; + boolean hasSeconds = true; if (suppressLeadingZeroElements) { - // this is a temporary marker on the front. Like ^ in regexp. - duration = " " + duration; - String tmp = StringUtils.replaceOnce(duration, " 0 days", StringUtils.EMPTY); + String tmp = StringUtils.removeStart(duration, "0 days "); if (tmp.length() != duration.length()) { + hasDays = false; duration = tmp; - tmp = StringUtils.replaceOnce(duration, " 0 hours", StringUtils.EMPTY); + tmp = StringUtils.removeStart(duration, "0 hours "); if (tmp.length() != duration.length()) { + hasHours = false; duration = tmp; - tmp = StringUtils.replaceOnce(duration, " 0 minutes", StringUtils.EMPTY); - duration = tmp; + tmp = StringUtils.removeStart(duration, "0 minutes "); if (tmp.length() != duration.length()) { - duration = StringUtils.replaceOnce(tmp, " 0 seconds", StringUtils.EMPTY); + hasMinutes = false; + duration = tmp; } } } - if (!duration.isEmpty()) { - // strip the space off again - duration = duration.substring(1); - } } if (suppressTrailingZeroElements) { - String tmp = StringUtils.replaceOnce(duration, " 0 seconds", StringUtils.EMPTY); + String tmp = StringUtils.removeEnd(duration, " 0 seconds"); if (tmp.length() != duration.length()) { + hasSeconds = false; duration = tmp; - tmp = StringUtils.replaceOnce(duration, " 0 minutes", StringUtils.EMPTY); - if (tmp.length() != duration.length()) { - duration = tmp; - tmp = StringUtils.replaceOnce(duration, " 0 hours", StringUtils.EMPTY); + if (hasMinutes) { + tmp = StringUtils.removeEnd(duration, " 0 minutes"); if (tmp.length() != duration.length()) { - duration = StringUtils.replaceOnce(tmp, " 0 days", StringUtils.EMPTY); + hasMinutes = false; + duration = tmp; + if (hasHours) { + tmp = StringUtils.removeEnd(duration, " 0 hours"); + if (tmp.length() != duration.length()) { + hasHours = false; + duration = tmp; + } + } } } } } // handle plurals duration = " " + duration; - duration = StringUtils.replaceOnce(duration, " 1 seconds", " 1 second"); - duration = StringUtils.replaceOnce(duration, " 1 minutes", " 1 minute"); - duration = StringUtils.replaceOnce(duration, " 1 hours", " 1 hour"); - duration = StringUtils.replaceOnce(duration, " 1 days", " 1 day"); - return duration.trim(); + if (hasSeconds) { + duration = StringUtils.replaceOnce(duration, " 1 seconds", " 1 second"); + } + if (hasMinutes) { + duration = StringUtils.replaceOnce(duration, " 1 minutes", " 1 minute"); + } + if (hasHours) { + duration = StringUtils.replaceOnce(duration, " 1 hours", " 1 hour"); + } + if (hasDays) { + duration = StringUtils.replaceOnce(duration, " 1 days", " 1 day"); + } + return duration.substring(1); } /** diff --git a/src/test/java/org/apache/commons/lang3/time/DurationFormatUtilsTest.java b/src/test/java/org/apache/commons/lang3/time/DurationFormatUtilsTest.java index 2266abb4ab6..404d08a78c7 100644 --- a/src/test/java/org/apache/commons/lang3/time/DurationFormatUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/time/DurationFormatUtilsTest.java @@ -331,6 +331,8 @@ public void testFormatDurationPluralWords() { public void testFormatDurationWords() { String text; + text = DurationFormatUtils.formatDurationWords(0, true, false); + assertEquals("0 seconds", text); text = DurationFormatUtils.formatDurationWords(50 * 1000, true, false); assertEquals("50 seconds", text); text = DurationFormatUtils.formatDurationWords(65 * 1000, true, false); @@ -344,6 +346,8 @@ public void testFormatDurationWords() { text = DurationFormatUtils.formatDurationWords(24 * 60 * 60 * 1000, true, false); assertEquals("1 day 0 hours 0 minutes 0 seconds", text); + text = DurationFormatUtils.formatDurationWords(0, true, true); + assertEquals("0 seconds", text); text = DurationFormatUtils.formatDurationWords(50 * 1000, true, true); assertEquals("50 seconds", text); text = DurationFormatUtils.formatDurationWords(65 * 1000, true, true); @@ -357,6 +361,8 @@ public void testFormatDurationWords() { text = DurationFormatUtils.formatDurationWords(24 * 60 * 60 * 1000, true, true); assertEquals("1 day", text); + text = DurationFormatUtils.formatDurationWords(0, false, true); + assertEquals("0 days", text); text = DurationFormatUtils.formatDurationWords(50 * 1000, false, true); assertEquals("0 days 0 hours 0 minutes 50 seconds", text); text = DurationFormatUtils.formatDurationWords(65 * 1000, false, true); @@ -370,6 +376,8 @@ public void testFormatDurationWords() { text = DurationFormatUtils.formatDurationWords(24 * 60 * 60 * 1000, false, true); assertEquals("1 day", text); + text = DurationFormatUtils.formatDurationWords(0, false, false); + assertEquals("0 days 0 hours 0 minutes 0 seconds", text); text = DurationFormatUtils.formatDurationWords(50 * 1000, false, false); assertEquals("0 days 0 hours 0 minutes 50 seconds", text); text = DurationFormatUtils.formatDurationWords(65 * 1000, false, false);