package rocks.inspectit.ui.rcp.formatter;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
/**
* This class is for formatting some output.
*
* @author Eduard Tudenhoefner
*
*/
public final class NumberFormatter {
/**
* Abbreviation character for the decimal metric unit.
*/
private static final String[] BINARY_METRIC_UNITS = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei" };
/**
* Formats a decimal number with the specific pattern.
*/
private static DecimalFormat decFormat = new DecimalFormat("###0.##");
/**
* Formats a decimal number and returns it in milliseconds format.
*/
private static DecimalFormat millisFormat = new DecimalFormat("0.00");
/**
* Formats a decimal number and returns it in nanoseconds format.
*/
private static DecimalFormat nanosFormat = new DecimalFormat("0.00");
/**
* Formats a decimal number with the specified pattern.
*/
private static DecimalFormat cpuFormat = new DecimalFormat("#.##");
/**
* Formats a decimal number with the specified pattern.
*/
private static DecimalFormat intFormat = new DecimalFormat("###");
/**
* Formats a decimal number with the specified pattern.
*/
private static DecimalFormat doubleFormat = new DecimalFormat("0.000");
/**
* Formats a decimal number without the specified pattern.
*/
private static DecimalFormat doubleUnspecificFormat = new DecimalFormat();
/**
* Formats a date/time value with the specified pattern.
*/
private static DateFormat dateMillisFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss.SSS");
/**
* Formats a date/time value with the specified pattern.
*/
private static DateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
static {
doubleUnspecificFormat.setGroupingSize(0);
}
/**
* The default private constructor.
*/
private NumberFormatter() {
}
/**
* Converts time in milliseconds to a <code>String</code> in the format HH:mm:ss.
*
* @param time
* the time in milliseconds.
* @return a <code>String</code> representing the time in the format HH:mm:ss.
*/
public static String millisecondsToString(long time) {
int seconds = (int) ((time / 1000) % 60);
int minutes = (int) ((time / 60000) % 60);
int hours = (int) ((time / 3600000) % 24);
int days = (int) ((time / 3600000) / 24);
StringBuilder builder = new StringBuilder();
builder.append(days);
builder.append("d ");
builder.append(hours);
builder.append("h ");
builder.append(minutes);
builder.append("m ");
builder.append(seconds);
builder.append('s');
return builder.toString();
}
/**
* Formats the time to a String value with milliseconds.
*
* @param time
* The time as long value.
* @return The formatted string.
*/
public static String formatTimeWithMillis(long time) {
return formatTimeWithMillis(new Date(time));
}
/**
* Formats the time to a String value with milliseconds.
*
* @param date
* The date to format.
* @return The formatted string.
*/
public static String formatTimeWithMillis(Date date) {
synchronized (dateMillisFormat) {
return dateMillisFormat.format(date);
}
}
/**
* Formats the time to a String value.
*
* @param time
* The time as long value.
* @return The formatted string.
*/
public static String formatTime(long time) {
return formatTime(new Date(time));
}
/**
* Formats the time to a String value.
*
* @param date
* The date to format.
* @return The formatted string.
*/
public static String formatTime(Date date) {
synchronized (dateFormat) {
return dateFormat.format(date);
}
}
/**
* Formats nanoseconds to seconds.
*
* @param time
* The time as long value.
* @return A formatted string.
*/
public static String formatNanosToSeconds(long time) {
double sec = time / 1000000000d;
return nanosFormat.format(sec) + " s";
}
/**
* Formats milliseconds to seconds.
*
* @param time
* The time as long value.
* @return A formatted string.
*/
public static String formatMillisToSeconds(long time) {
double sec = time / 1000d;
return millisFormat.format(sec) + " s";
}
/**
* Formats bytes to kiloBytes.
*
* @param bytes
* The bytes to format.
* @return A formatted string.
*/
public static String formatBytesToKBytes(long bytes) {
return decFormat.format((double) bytes / 1024) + " Kb";
}
/**
* Formats bytes to megaBytes.
*
* @param bytes
* The bytes to format.
* @return A formatted string.
*/
public static String formatBytesToMBytes(long bytes) {
return decFormat.format((double) bytes / (1024 * 1024)) + " Mb";
}
/**
* Adds a %-sign to a floating number. For example: input = 12 / output = 12 %.
*
* @param percent
* The value to format.
* @return The formatted string.
*/
public static String formatCpuPercent(float percent) {
return cpuFormat.format(percent) + " %";
}
/**
* Formats an integer value. For example: input = 1234567 / output = 1,234,567.
*
* @param number
* The value to format.
* @return The formatted String.
*/
public static String formatInteger(int number) {
return intFormat.format(number);
}
/**
* Formats a long value. For example: input = 1234567 / output = 1,234,567.
*
* @param number
* The value to format.
* @return The formatted string.
*/
public static String formatLong(long number) {
return intFormat.format(number);
}
/**
* Formats a double value. For example: input = 123545.9876543 / output = 123545.987.
*
* @param number
* The value to format.
* @return The formatted string.
*/
public static String formatDouble(double number) {
return doubleFormat.format(number);
}
/**
* Formats a double value based on the number of decimal places.
*
* @param number
* The value to format.
* @param decimalPlaces
* Number of decimal places.
* @return The formatted string.
*/
public static String formatDouble(double number, int decimalPlaces) {
doubleUnspecificFormat.setMaximumFractionDigits(decimalPlaces);
doubleUnspecificFormat.setMinimumFractionDigits(decimalPlaces);
return doubleUnspecificFormat.format(number);
}
/**
* Returns the human readable bytes number with one decimal place.
*
* @param bytes
* Bytes to transform.
* @return Human readable string.
*/
public static String humanReadableByteCount(long bytes) {
return humanReadableByteCount(bytes, 1);
}
/**
* Returns the human readable bytes number with the specified amount of decimal places.
* <p>
* <b>IMPORTANT:</b> The method code is based on <a href=
* "http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java"
* >stackoverflow</a>. Original author is aioobe. License info can be found
* <a href="http://creativecommons.org/licenses/by-sa/3.0/">here</a>.
*
* @param bytes
* Bytes to transform.
* @param decimalPlaces
* Amount of decimal places.
* @return Human readable string.
*/
public static String humanReadableByteCount(long bytes, int decimalPlaces) {
if (bytes < 1024L) {
return bytes + " B";
}
int sizeIndex = (int) (Math.log(bytes) / Math.log(1024D));
double value = bytes / Math.pow(1024D, sizeIndex);
return String.format(Locale.US, "%." + decimalPlaces + "f %sB", value, BINARY_METRIC_UNITS[sizeIndex]);
}
/**
* Returns the human readable millis count.
*
* If <b>shortDescription</b> is <code>true</code> then the format will be: x
* days/hours/minutes/seconds depending on the time. Meaning if more than day has passed only 1
* day will be returned. Otherwise if between 23-24 hours passed, 23 hours will be returned.
*
* If <b>shortDescrption</b> is <code>false</code> then the the returned format is xd, xh, xm,
* xs.. Not that if any unit is 0 it won't be printed.
*
* @param millis
* Number of milliseconds.
* @param shortDescription
* Short or long description.
* @return Formated string.
*/
public static String humanReadableMillisCount(long millis, boolean shortDescription) {
StringBuilder stringBuilder = new StringBuilder();
boolean started = false;
long days = TimeUnit.MILLISECONDS.toDays(millis);
if (days > 0) {
if (shortDescription) {
return days + " day" + (days > 1 ? "s" : "");
}
stringBuilder.append(String.format("%dd", days));
started = true;
}
long hours = TimeUnit.MILLISECONDS.toHours(millis) - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(millis));
if (started) {
stringBuilder.append(String.format(" %dh", hours));
} else if (hours > 0) {
if (shortDescription) {
return hours + " hour" + (hours > 1 ? "s" : "");
}
stringBuilder.append(String.format("%dh", hours));
started = true;
}
long min = TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis));
if (started) {
stringBuilder.append(String.format(" %dm", min));
} else if (min > 0) {
if (shortDescription) {
return min + " minute" + (min > 1 ? "s" : "");
}
stringBuilder.append(String.format("%dm", min));
started = true;
}
long sec = TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis));
if (started) {
stringBuilder.append(String.format(" %ds", sec));
} else if (sec > 0) {
if (shortDescription) {
return sec + " second" + (sec > 1 ? "s" : "");
}
stringBuilder.append(String.format("%ds", sec));
started = true;
}
return stringBuilder.toString();
}
/**
* Converts a double into a percentage string. For example: input = 0.1525 / output = 15.25 %
*
* @param percentage
* the percentage value
* @return The formatted string
*/
public static String formatDoubleToPercent(double percentage) {
return doubleFormat.format(percentage * 100D) + " %";
}
}