[platform] simpler unit formatting code; SI-compliant info units

... also drops unused code and pushes non-RT methods back into 'util'
This commit is contained in:
Roman Shevchenko
2018-08-14 15:44:10 +02:00
parent 93f799ec3f
commit e463fa498f
3 changed files with 51 additions and 124 deletions
@@ -5,6 +5,7 @@ import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
@@ -364,20 +365,6 @@ public class StringUtilRt {
return result;
}
@NotNull
@Contract(pure = true)
public static String formatNumber(long number) {
return formatNumber(number, "");
}
@NotNull
@Contract(pure = true)
public static String formatNumber(long number, @NotNull String unitSeparator) {
return formatValue(number, null, unitSeparator,
new String[]{"", "K", "M", "G", "T", "P", "E"},
new long[]{1, 1000, 1000, 1000, 1000, 1000, 1000});
}
@NotNull
@Contract(pure = true)
public static String formatFileSize(long fileSize) {
@@ -387,67 +374,12 @@ public class StringUtilRt {
@NotNull
@Contract(pure = true)
public static String formatFileSize(long fileSize, @NotNull String unitSeparator) {
return formatValue(fileSize, null, unitSeparator,
new String[]{"B", "KB", "MB", "GB", "TB", "PB", "EB"},
new long[]{1, 1024, 1024, 1024, 1024, 1024, 1024});
}
@NotNull
@Contract(pure = true)
public static String formatDuration(long duration) {
return formatDuration(duration, " ");
}
@NotNull
@Contract(pure = true)
public static String formatDuration(long duration, @NotNull String unitSeparator) {
return formatValue(duration, " ", unitSeparator,
new String[]{"ms", "s", "m", "h", "d", "mo", "yr", "c", "ml", "ep"},
new long[]{1, 1000, 60, 60, 24, 30, 12, 100, 10, 10000});
}
@NotNull
private static String formatValue(long value, @Nullable String partSeparator, String unitSeparator, String[] units, long[] multipliers) {
if (units.length != multipliers.length) {
throw new IllegalArgumentException(units.length + " != " + multipliers.length);
}
StringBuilder sb = new StringBuilder();
long count = value;
long remainder = 0;
int i = 1;
for (; i < units.length && count > 0; i++) {
long multiplier = multipliers[i];
if (count < multiplier) break;
remainder = count % multiplier;
count /= multiplier;
if (partSeparator != null && (remainder != 0 || sb.length() > 0)) {
if (units[i - 1].length() > 0) {
sb.insert(0, units[i - 1]);
sb.insert(0, unitSeparator);
}
sb.insert(0, remainder).insert(0, partSeparator);
}
else {
remainder = Math.round(remainder * 100 / (double)multiplier);
count += remainder / 100;
remainder %= 100;
}
}
if (partSeparator != null || remainder == 0) {
if (units[i - 1].length() > 0) {
sb.insert(0, units[i - 1]);
sb.insert(0, unitSeparator);
}
sb.insert(0, count);
}
else if (remainder > 0) {
sb.append(count).append(".").append(remainder / 10 == 0 ? "0" : "").append(remainder);
if (units[i - 1].length() > 0) {
sb.append(unitSeparator);
sb.append(units[i - 1]);
}
}
return sb.toString();
if (fileSize < 0) throw new IllegalArgumentException("Invalid value: " + fileSize);
if (fileSize == 0) return '0' + unitSeparator + 'B';
int rank = (int)(Math.log10(fileSize) / 3);
double value = fileSize / Math.pow(1000, rank);
String[] units = {"B", "kB", "MB", "GB", "TB", "PB", "EB"};
return new DecimalFormat("#,##0.##").format(value) + unitSeparator + units[rank];
}
@Contract(pure = true)
@@ -1547,47 +1547,60 @@ public class StringUtil extends StringUtilRt {
return text;
}
@NotNull
@Contract(pure = true)
public static String formatNumber(long number) {
return StringUtilRt.formatNumber(number);
}
@NotNull
@Contract(pure = true)
public static String formatNumber(long number, @NotNull String unitSeparator) {
return StringUtilRt.formatNumber(number, unitSeparator);
}
/**
* Formats the specified file size as a string.
*
* @param fileSize the size to format.
* @return the size formatted as a string.
* @since 5.0.1
*/
/** Formats given file size in metric (1 kB = 1000 B) units (example: {@code formatFileSize(1234) = "1.23 KB"}). */
@NotNull
@Contract(pure = true)
public static String formatFileSize(long fileSize) {
return StringUtilRt.formatFileSize(fileSize);
}
/** Formats given file size in metric (1 kB = 1000 B) units (example: {@code formatFileSize(1234, "") = "1.23KB"}). */
@NotNull
@Contract(pure = true)
public static String formatFileSize(long fileSize, @NotNull String unitSeparator) {
return StringUtilRt.formatFileSize(fileSize, unitSeparator);
}
/** Formats given duration as a sum of time units (example: {@code formatDuration(123456) = "2 m 3 s 456 ms"}). */
@NotNull
@Contract(pure = true)
public static String formatDuration(long duration) {
return StringUtilRt.formatDuration(duration);
return formatDuration(duration, " ");
}
/** Formats given duration as a sum of time units (example: {@code formatDuration(123456, "") = "2m 3s 456ms"}). */
@NotNull
@Contract(pure = true)
public static String formatDuration(long duration, @NotNull String unitSeparator) {
return StringUtilRt.formatDuration(duration, unitSeparator);
String[] units = {"ms", "s", "m", "h", "d", "mo", "yr", "c", "ml", "ep"};
long[] multipliers = {1, 1000, 60, 60, 24, 30, 12, 100, 10, 10000};
StringBuilder sb = new StringBuilder();
long count = duration, remainder;
int i = 1;
for (; i < units.length && count > 0; i++) {
long multiplier = multipliers[i];
if (count < multiplier) break;
remainder = count % multiplier;
count /= multiplier;
if (remainder != 0 || sb.length() > 0) {
if (units[i - 1].length() > 0) {
sb.insert(0, units[i - 1]);
sb.insert(0, unitSeparator);
}
sb.insert(0, remainder).insert(0, " ");
}
else {
remainder = Math.round(remainder * 100 / (double)multiplier);
count += remainder / 100;
}
}
if (units[i - 1].length() > 0) {
sb.insert(0, units[i - 1]);
sb.insert(0, unitSeparator);
}
sb.insert(0, count);
return sb.toString();
}
/**
@@ -492,36 +492,18 @@ public class StringUtilTest {
public void testFormatFileSize() {
assertEquals("0 B", StringUtil.formatFileSize(0));
assertEquals("1 B", StringUtil.formatFileSize(1));
assertEquals("2 GB", StringUtil.formatFileSize(Integer.MAX_VALUE));
assertEquals("8 EB", StringUtil.formatFileSize(Long.MAX_VALUE));
assertEquals("2.15 GB", StringUtil.formatFileSize(Integer.MAX_VALUE));
assertEquals("9.22 EB", StringUtil.formatFileSize(Long.MAX_VALUE));
assertEquals("58.69 KB", StringUtil.formatFileSize(60100));
assertEquals("60.1 kB", StringUtil.formatFileSize(60100));
assertEquals("1.21 KB", StringUtil.formatFileSize(1234));
assertEquals("12.06 KB", StringUtil.formatFileSize(12345));
assertEquals("120.56 KB", StringUtil.formatFileSize(123456));
assertEquals("1.18 MB", StringUtil.formatFileSize(1234567));
assertEquals("11.77 MB", StringUtil.formatFileSize(12345678));
assertEquals("117.74 MB", StringUtil.formatFileSize(123456789));
assertEquals("1.15 GB", StringUtil.formatFileSize(1234567890));
}
@Test
public void testFormatNumber() {
assertEquals("0", StringUtil.formatNumber(0));
assertEquals("1", StringUtil.formatNumber(1));
assertEquals("2.15G", StringUtil.formatNumber(Integer.MAX_VALUE));
assertEquals("9.22E", StringUtil.formatNumber(Long.MAX_VALUE));
assertEquals("60.10K", StringUtil.formatNumber(60100));
assertEquals("1.23K", StringUtil.formatNumber(1234));
assertEquals("12.35K", StringUtil.formatNumber(12345));
assertEquals("123.46K", StringUtil.formatNumber(123456));
assertEquals("1.23M", StringUtil.formatNumber(1234567));
assertEquals("12.35M", StringUtil.formatNumber(12345678));
assertEquals("123.46M", StringUtil.formatNumber(123456789));
assertEquals("1.23G", StringUtil.formatNumber(1234567890));
assertEquals("1.23 kB", StringUtil.formatFileSize(1234));
assertEquals("12.35 kB", StringUtil.formatFileSize(12345));
assertEquals("123.46 kB", StringUtil.formatFileSize(123456));
assertEquals("1.23 MB", StringUtil.formatFileSize(1234567));
assertEquals("12.35 MB", StringUtil.formatFileSize(12345678));
assertEquals("123.46 MB", StringUtil.formatFileSize(123456789));
assertEquals("1.23 GB", StringUtil.formatFileSize(1234567890));
}
@Test