Как преобразовать миллисекунды в "X мин, X сек" на Java?
Я хочу записывать время, используя System.currentTimeMillis()
, когда пользователь начинает что-то в моей программе. Когда он завершает, я собираюсь вычесть текущее значение System.currentTimeMillis()
из переменной start
и хотел бы отобразить прошедшее время в удобочитаемом формате, таком как "XX часов, XX минут, XX секунд" или даже "XX минут, XX секунд", так как маловероятно, что это займет у пользователя целый час.
Как лучше всего это реализовать?
5 ответ(ов)
На основе ответа @siddhadev, я написал функцию, которая конвертирует миллисекунды в форматированную строку:
/**
* Преобразует длительность в миллисекундах в строковый формат
*
* @param millis Длительность, которую нужно преобразовать в строку
* @return Строка формата "X Дней Y Часов Z Минут A Секунд".
*/
public static String getDurationBreakdown(long millis) {
if (millis < 0) {
throw new IllegalArgumentException("Длительность должна быть больше нуля!");
}
long days = TimeUnit.MILLISECONDS.toDays(millis);
millis -= TimeUnit.DAYS.toMillis(days);
long hours = TimeUnit.MILLISECONDS.toHours(millis);
millis -= TimeUnit.HOURS.toMillis(hours);
long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
millis -= TimeUnit.MINUTES.toMillis(minutes);
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);
StringBuilder sb = new StringBuilder(64);
sb.append(days);
sb.append(" Дней ");
sb.append(hours);
sb.append(" Часов ");
sb.append(minutes);
sb.append(" Минут ");
sb.append(seconds);
sb.append(" Секунд");
return sb.toString();
}
Эта функция принимает длительность в миллисекундах и возвращает строку с разложением времени на дни, часы, минуты и секунды. Обратите внимание на проверку на отрицательные значения, что помогает избежать некорректных входных данных.
Ваш код использует SimpleDateFormat
для форматирования времени, но есть несколько нюансов, которые нужно учесть.
SimpleDateFormat("mm:ss:SSS")
форматирует минуты (mm), секунды (ss) и миллисекунды (SSS). Однако, еслиtime
- это время в миллисекундах с начала эпохи Unix (01.01.1970), то вывод будет неправилен, так как он будет возвращать время с 1970 года.Если
time
представляет собой количество миллисекунд, прошедших с нуля (например, 1536259 миллисекунд), вам нужно будет сначала преобразовать это время в нужный формат. Попробуйте следующий код:
long time = 1536259; // это время в миллисекундах
long minutes = (time / 60000) % 60;
long seconds = (time / 1000) % 60;
long milliseconds = time % 1000;
String formattedTime = String.format("%02d:%02d:%03d", minutes, seconds, milliseconds);
return formattedTime;
Этот код позволит вам получить нужный формат времени, который возвращает строку "25:36:259" для вашего значения time = 1536259
миллисекунд.
Вопрос о количестве миллисекунд в секунде и минуте довольно прост. Чтобы ответить на него, напомню, что в одной секунде 1000 миллисекунд, а в одной минуте 60 секунд.
Таким образом, для получения количества миллисекунд в минуте мы можем сделать следующее вычисление:
int millisecondsInASecond = 1000;
int millisecondsInAMinute = millisecondsInASecond * 60; // 60 секунд
Если мы продолжим аналогичный подход для других единиц времени, получим:
int millisecondsInAnHour = millisecondsInAMinute * 60; // 60 минут
int millisecondsInADay = millisecondsInAnHour * 24; // 24 часа
int millisecondsInAWeek = millisecondsInADay * 7; // 7 дней
int millisecondsInAMonth = millisecondsInADay * 30; // приблизительно 30 дней
int millisecondsInAYear = millisecondsInADay * 365; // 365 дней
int millisecondsInADecade = millisecondsInAYear * 10; // 10 лет
Не забудьте, что количество дней в месяце может варьироваться, а в году есть високосные года, поэтому для более точных расчетов может понадобиться использовать специальные библиотеки или учесть это в расчетах.
Если у вас есть дополнительные вопросы, не стесняйтесь спрашивать!
Чтобы дополнить информацию по формату времени в виде HH:mm:ss, где:
- 0 ⇐ HH ⇐ бесконечность
- 0 ⇐ mm < 60
- 0 ⇐ ss < 60
вы можете воспользоваться следующим кодом:
int h = (int) ((startTimeInMillis / 1000) / 3600);
int m = (int) (((startTimeInMillis / 1000) / 60) % 60);
int s = (int) ((startTimeInMillis / 1000) % 60);
Я только что столкнулся с этой проблемой и разобрался в ней.
Кратчайшее решение:
Вот, вероятно, кратчайшее решение, которое также учитывает часовые пояса.
System.out.printf("%tT", millis - TimeZone.getDefault().getRawOffset());
Например, вывод будет таким:
00:18:32
Пояснение:
%tT
форматирует время в 24-часовом формате как %tH:%tM:%tS
.
%tT
также принимает длинные значения в качестве входных данных, поэтому нет необходимости создавать объект Date
. Метод printf()
просто выведет время, указанное в миллисекундах, но в текущем часовом поясе, поэтому нам нужно вычесть "сырую" смещение текущего часового пояса, чтобы 0 миллисекунд соответствовало 0 часам, а не значению смещения времени текущего часового пояса.
Примечание #1: Если вам нужен результат в виде String
, вы можете получить его таким образом:
String t = String.format("%tT", millis - TimeZone.getDefault().getRawOffset());
Примечание #2: Это решение будет работать корректно только в том случае, если millis
меньше дня, поскольку часть, относящаяся к дню, не включена в вывод.
Преобразование строки в дату в Java
Почему нет ConcurrentHashSet, если есть ConcurrentHashMap?
Eclipse/Java: не работает автозавершение кода
Как объявить массив в одну строку?
Загрузка JDK Java на Linux через wget приводит к отображению страницы лицензии вместо установки