Wie konvertiert man Millisekunden in das Format “hh: mm: ss”?

Ich bin verwirrt. Nachdem ich über diesen Thread gestolpert war, versuchte ich herauszufinden, wie man einen Countdown-Timer formatiert, der das Format hh:mm:ss .

Hier ist mein Versuch –

 //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))); 

Also, wenn ich einen Wert wie 3600000ms versuche, 3600000ms ich 01:59:00 , was falsch ist, da es 01:00:00 sein 01:00:00 . Offensichtlich stimmt etwas nicht mit meiner Logik, aber im Moment kann ich nicht sehen, was es ist!

Kann jemand helfen?

Bearbeiten –

Behoben. Hier ist der richtige Weg, um Millisekunden in das Format hh:mm:ss formatieren –

 //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)))); 

Das Problem war dieses TimeUnit.MINUTES.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)) . Es sollte stattdessen TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)) .

Du warst wirklich nah dran:

 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))); 

Sie haben Stunden in Millisekunden umgerechnet, indem Sie Minuten anstelle von Stunden verwenden .

Übrigens, ich mag Ihre Verwendung der TimeUnit API 🙂

Hier ist ein Testcode:

 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); } 

Ausgabe:

 01:00:00 

Ich erkannte, dass mein Code oben durch die Verwendung einer Modul-Division anstelle einer Subtraktion stark vereinfacht werden kann:

 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)); 

Immer noch die TimeUnit API für alle magischen Werte und gibt genau die gleiche Ausgabe.

Die generische Methode dafür ist ziemlich einfach:

 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); } 

Wenn Sie Apache Commons verwenden:

 DurationFormatUtils.formatDuration(timeInMS, "HH:mm:ss,SSS"); 
 // 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 ); 

Siehe ausführbares Beispiel mit einer Eingabe von 1200 ms.

Ich habe das benutzt:

 String.format("%1$tH:%1$tM:%1$tS.%1$tL", millis); 

Siehe Beschreibung der class Formatter .

Siehe ausführbares Beispiel mit Eingabe von 2400 ms.

 DateFormat df = new SimpleDateFormat("HH:mm:ss"); String formatted = df.format(aDateObject); 

Testergebnisse für die 4 Implementierungen

Da wir sehr viel Formatierung für riesige Datenmengen machen mussten, brauchten wir die beste performance. Hier sind die (überraschenden) Ergebnisse:

für (int i = 0; i <1000000; i ++) {FUNCTION_CALL}

Dauer:

  • KombinationFormatter: 196 Millis
  • FormatDauer: 272 Millis
  • apacheFormat: 754 Millis
  • formatTimeUnit: 2216 Millis

     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(); } 

Der folgende Code führt die Konvertierung in beide Richtungen durch

23: 59: 58: 999 bis 86398999

und dann

86398999 bis 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 ie "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 ie * 34137999 that can be obtained as follows; * 

* long lH = h * 60 * 60 * 1000; //hour to milli *

* long lM = m * 60 * 1000; // minute to milli *

* long lS = s * 1000; //seconds to milli *

* millis = lH + lM + lS + ms; * @return a string formatted as HH:MM:SS:MSMS ie "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; } }

Nach der Antwort von Bohemian brauchen wir TimeUnit nicht, um einen bekannten Wert zu finden. Viel besser wäre der Code

 String hms = String.format("%02d:%02d:%02d", millisLeft/(3600*1000), millisLeft/(60*1000) % 60, millisLeft/1000 % 60); 

Ich hoffe es hilft

  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 } 

Ich habe versucht, wie in der ersten Antwort gezeigt. Es funktioniert, aber Minus brachte mich in Verwirrung. Meine Antwort von 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]) } 
  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))); 

Format: 00: 00: 00.000

Beispiel: 615605 Millisecend

00: 10: 15.605

Nun, du könntest so etwas ausprobieren:

 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; } 

um Millisekunden in einen Zeitwert zu konvertieren

Die als richtig markierte Antwort hat einen kleinen Fehler,

 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))); 

Zum Beispiel ist dies ein Beispiel für den Wert, den ich bekomme:

 417474:44:19 

Dies ist die Lösung, um das richtige Format zu erhalten:

 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))); 

als Ergebnis ein korrektes Format bekommen:

 18:44:19 

andere Option, um das Format zu erhalten hh:mm:ss ist nur:

  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); 

Dies druckt:

01:00:00

Sie machen recht, wenn Sie zulassen, dass Bibliotheksmethoden die Conversions für Sie durchführen. java.time , die moderne Java-API für Datum und Uhrzeit, oder genauer gesagt, die Duration class macht sie eleganter und weniger errorsanfällig als TimeUnit .

Die Methoden toMinutesPart und toSecondsPart , die ich verwendet habe, wurden in Java 9 eingeführt.

Java 6, 7 und 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); 

Die Ausgabe ist die gleiche wie oben.

Frage: Wie kann das in Java 6 und 7 funktionieren?

  • In Java 8 und höher und auf neueren Android-Geräten (ab API-Level 26, wie mir gesagt wurde) kommt java.time eingebaut.
  • In Java 6 und 7 erhalten Sie den ThreeTen Backport, den Backport der modernen classn (ThreeTen für JSR 310; siehe die Links unten).
  • Auf (älteren) Android-Geräten verwenden Sie die Android-Version von ThreeTen Backport. Es heißt ThreeTenABP. Und stellen Sie sicher, dass Sie die Datums- und org.threeten.bp von org.threeten.bp mit Unterpaketen importieren.

Links

  • Oracle-Lernprogramm: Date Time , das die Verwendung von java.time .
  • Java Specification Request (JSR) 310 , wobei java.time zuerst beschrieben wurde.
  • ThreeTen Backport-Projekt , der Backport von java.time zu Java 6 und 7 (ThreeTen für JSR-310).
  • ThreeTenABP , Android Edition von ThreeTen Backport
  • Frage: Wie man ThreeTenABP in Android Project verwendet , mit einer sehr gründlichen Erklärung.

Für Kotlin

 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))) 

wo, milSecs ist Millisekunden