Как конвертировать миллисекунды в формат" чч:мм:СС"?
Я в замешательстве. После того, как наткнулся на этой thread, я попытался выяснить, как отформатировать таймер обратного отсчета, который имел формат hh:mm:ss
.
вот моя попытка -
//hh:mm:ss
String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) -
TimeUnit.MINUTES.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
Итак, когда я пытаюсь значение, как 3600000ms
, Я 01:59:00
, что неправильно, так как это должно быть 01:00:00
. Очевидно, что-то не так с моей логикой, но в данный момент я не вижу, что это такое!
может кто-нибудь помочь?
изменить -
исправил. Вот правильный способ форматирования миллисекунд в hh:mm:ss!--12-->
//hh:mm:ss
String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))));
проблема была в этом TimeUnit.MINUTES.toMinutes(TimeUnit.MILLISECONDS.toHours(millis))
. Это должно было быть так .
16 ответов:
ты действительно рядом:
String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis), TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), // The change is in this line TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
вы переводили часы в миллисекунды с помощью минут вместо часа.
кстати, мне нравится ваше использование
TimeUnit
API:)вот некоторые тестовый код:
public static void main(String[] args) throws ParseException { long millis = 3600000; String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis), TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))); System.out.println(hms); }
выход:
01:00:00
я понял, что мой код выше может быть значительно упрощен с помощью деления по модулю вместо вычитания:
String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis), TimeUnit.MILLISECONDS.toMinutes(millis) % TimeUnit.HOURS.toMinutes(1), TimeUnit.MILLISECONDS.toSeconds(millis) % TimeUnit.MINUTES.toSeconds(1));
все еще используя
TimeUnit
API для всех магических значений, и дает точно такой же результат.
общий метод для этого довольно прост:
public static String convertSecondsToHMmSs(long seconds) { long s = seconds % 60; long m = (seconds / 60) % 60; long h = (seconds / (60 * 60)) % 24; return String.format("%d:%02d:%02d", h,m,s); }
// New date object from millis Date date = new Date(millis); // formattter SimpleDateFormat formatter= new SimpleDateFormat("HH:mm:ss.SSS"); formatter.setTimeZone(TimeZone.getTimeZone("UTC")); // Pass date object String formatted = formatter.format(date );
посмотреть выполнимое пример используя входной сигнал 1200 МС.
я использовал этот:
String.format("%1$tH:%1$tM:%1$tS.%1$tL", millis);
смотрите описание класса форматер.
посмотреть выполнимое пример используя входной сигнал 2400 МС.
результаты тестирования для 4 реализаций
чтобы сделать много форматирования для огромных данных, необходима лучшая производительность, поэтому вот (удивительные) результаты:
for (int i = 0; i
продолжительность:
- combinationFormatter:196 миллисе
- formatDuration: 272 миллисе
- apacheFormat: 754 Миллис
formatTimeUnit: 2216 Миллис
public static String apacheFormat(long millis) throws ParseException { return DurationFormatUtils.formatDuration(millis, "HH:mm:ss"); } public static String formatTimeUnit(long millis) throws ParseException { String formatted = String.format( "%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis), TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))); return formatted; } public static String formatDuration(final long millis) { long seconds = (millis / 1000) % 60; long minutes = (millis / (1000 * 60)) % 60; long hours = millis / (1000 * 60 * 60); StringBuilder b = new StringBuilder(); b.append(hours == 0 ? "00" : hours < 10 ? String.valueOf("0" + hours) : String.valueOf(hours)); b.append(":"); b.append(minutes == 0 ? "00" : minutes < 10 ? String.valueOf("0" + minutes) : String.valueOf(minutes)); b.append(":"); b.append(seconds == 0 ? "00" : seconds < 10 ? String.valueOf("0" + seconds) : String.valueOf(seconds)); return b.toString(); } public static String combinationFormatter(final long millis) { long seconds = TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)); long minutes = TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)); long hours = TimeUnit.MILLISECONDS.toHours(millis); StringBuilder b = new StringBuilder(); b.append(hours == 0 ? "00" : hours < 10 ? String.valueOf("0" + hours) : String.valueOf(hours)); b.append(":"); b.append(minutes == 0 ? "00" : minutes < 10 ? String.valueOf("0" + minutes) : String.valueOf(minutes)); b.append(":"); b.append(seconds == 0 ? "00" : seconds < 10 ? String.valueOf("0" + seconds) : String.valueOf(seconds)); return b.toString(); }
приведенный ниже код выполняет преобразование в обоих направлениях
23:59:58:999 до 86398999
и
86398999 до 23: 59:58: 999
import java.util.concurrent.TimeUnit; public class TimeUtility { public static void main(String[] args) { long currentDateTime = System.currentTimeMillis(); String strTest = "23:59:58:999"; System.out.println(strTest); long l = strToMilli(strTest); System.out.println(l); l += 1; String str = milliToString(l); System.out.println(str); } /** * convert a time string into the equivalent long milliseconds * * @param strTime string fomratted as HH:MM:SS:MSMS i.e. "23:59:59:999" * @return long integer like 86399999 */ public static long strToMilli(String strTime) { long retVal = 0; String hour = strTime.substring(0, 2); String min = strTime.substring(3, 5); String sec = strTime.substring(6, 8); String milli = strTime.substring(9, 12); int h = Integer.parseInt(hour); int m = Integer.parseInt(min); int s = Integer.parseInt(sec); int ms = Integer.parseInt(milli); String strDebug = String.format("%02d:%02d:%02d:%03d", h, m, s, ms); //System.out.println(strDebug); long lH = h * 60 * 60 * 1000; long lM = m * 60 * 1000; long lS = s * 1000; retVal = lH + lM + lS + ms; return retVal; } /** * convert time in milliseconds to the corresponding string, in case of day * rollover start from scratch 23:59:59:999 + 1 = 00:00:00:000 * * @param millis the number of milliseconds corresponding to tim i.e. * 34137999 that can be obtained as follows; * <p> * long lH = h * 60 * 60 * 1000; //hour to milli * <p> * long lM = m * 60 * 1000; // minute to milli * <p> * long lS = s * 1000; //seconds to milli * <p> * millis = lH + lM + lS + ms; * @return a string formatted as HH:MM:SS:MSMS i.e. "23:59:59:999" */ private static String milliToString(long millis) { long hrs = TimeUnit.MILLISECONDS.toHours(millis) % 24; long min = TimeUnit.MILLISECONDS.toMinutes(millis) % 60; long sec = TimeUnit.MILLISECONDS.toSeconds(millis) % 60; //millis = millis - (hrs * 60 * 60 * 1000); //alternative way //millis = millis - (min * 60 * 1000); //millis = millis - (sec * 1000); //long mls = millis ; long mls = millis % 1000; String toRet = String.format("%02d:%02d:%02d:%03d", hrs, min, sec, mls); //System.out.println(toRet); return toRet; } }
исходя из ответа Bohemian нам не нужно использовать TimeUnit, чтобы найти известное значение. Гораздо более оптимальным кодом было бы
String hms = String.format("%02d:%02d:%02d", millisLeft/(3600*1000), millisLeft/(60*1000) % 60, millisLeft/1000 % 60);
надеюсь, что это помогает
String string = String.format("%02d:%02d:%02d.%03d", TimeUnit.MILLISECONDS.toHours(millisecend), TimeUnit.MILLISECONDS.toMinutes(millisecend) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millisecend)), TimeUnit.MILLISECONDS.toSeconds(millisecend) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisecend)), millisecend - TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(millisecend)));
формат: 00: 00: 00.000
Пример: 615605 Миллисекунд
00:10:15.605
public String millsToDateFormat(long mills) { Date date = new Date(mills); DateFormat formatter = new SimpleDateFormat("HH:mm:ss"); String dateFormatted = formatter.format(date); return dateFormatted; //note that it will give you the time in GMT+0 }
я попробовал как показано в первом ответе. Он работает, но минус привел меня в замешательство. Мой ответ от Groovy:
import static java.util.concurrent.TimeUnit.* ... private static String formatElapsedTime(long millis) { int hrs = MILLISECONDS.toHours(millis) % 24 int min = MILLISECONDS.toMinutes(millis) % 60 int sec = MILLISECONDS.toSeconds(millis) % 60 int mls = millis % 1000 sprintf( '%02d:%02d:%02d (%03d)', [hrs, min, sec, mls]) }
Ну, вы могли бы попробовать что-то вроде этого :
public String getElapsedTimeHoursMinutesSecondsString() { long elapsedTime = getElapsedTime(); String format = String.format("%%0%dd", 2); elapsedTime = elapsedTime / 1000; String seconds = String.format(format, elapsedTime % 60); String minutes = String.format(format, (elapsedTime % 3600) / 60); String hours = String.format(format, elapsedTime / 3600); String time = hours + ":" + minutes + ":" + seconds; return time; }
для преобразования миллисекунд в значение времени
ответ, отмеченный как правильный, имеет небольшую ошибку,
String myTime = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis), TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), // The change is in this line TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
например, это пример значения, которое я получаю:
417474:44:19
это решение, чтобы получить правильный формат:
String myTime = String.format("%02d:%02d:%02d", //Hours TimeUnit.MILLISECONDS.toHours(millis) - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(millis)), //Minutes TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), //Seconds TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
получение в результате правильного формата:
18:44:19
другой вариант, чтобы получить формат
hh:mm:ss
всего :Date myDate = new Date(timeinMillis); SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss"); String myTime = formatter.format(myDate);
Java 9
Duration timeLeft = Duration.ofMillis(3600000); String hhmmss = String.format("%02d:%02d:%02d", timeLeft.toHours(), timeLeft.toMinutesPart(), timeLeft.toSecondsPart()); System.out.println(hhmmss);
печатается:
01:00:00
вы делаете правильно, позволяя библиотечным методам выполнять преобразования, связанные с вами.
java.time
, современный JAVA date and time API, или точнее, егоDuration
класс делает это более элегантно и менее подверженным ошибкам, чемTimeUnit
.The
toMinutesPart
иtoSecondsPart
методы, которые я использовал, были введены в Java 9.в Java 6, 7 и 8
long hours = timeLeft.toHours(); timeLeft = timeLeft.minusHours(hours); long minutes = timeLeft.toMinutes(); timeLeft = timeLeft.minusMinutes(minutes); long seconds = timeLeft.toSeconds(); String hhmmss = String.format("%02d:%02d:%02d", hours, minutes, seconds); System.out.println(hhmmss);
выход такой же, как и выше.
вопрос: как это может работать в Java 6 и 7?
- в Java 8 и позже и на новых устройствах Android (от уровня API 26, мне сказали)
java.time
идет встроенный.- в Java 6 и 7 получите Threeten Backport, backport современных классов (ThreeTen для JSR 310; см. Ссылки внизу).
- на (более старом) Android используйте Android-версию Threeten Backport. Это называется ThreeTenABP. И убедитесь, что вы импортируете классы даты и времени из
org.threeten.bp
С подпакетами.ссылки
- Oracle tutorial: Date Time объясняя, как использовать
java.time
.- запрос спецификации Java (JSR) 310, где
java.time
была впервые описана.- ThreeTen Backport project на базу
java.time
к Java 6 и 7 (ThreeTen для JSR-310).- ThreeTenABP, Android издание Threeten Backport
- вопрос: Как использовать ThreeTenABP в проекте Android С очень подробного объяснения.
Для Котлин
val hours = String.format("%02d", TimeUnit.MILLISECONDS.toHours(milSecs)) val minutes = String.format("%02d", TimeUnit.MILLISECONDS.toMinutes(milSecs) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(milSecs))) val seconds = String.format("%02d", TimeUnit.MILLISECONDS.toSeconds(milSecs) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(milSecs)))
здесь
milSecs
миллисекунды