manejo localdatetime horas ejemplo java time

localdatetime - ¿Cómo convertir milisegundos a "X minutos, x segundos" en Java?



manejo de horas en java (25)

Tiempo de joda

Usando Joda-Time :

DateTime startTime = new DateTime(); // do something DateTime endTime = new DateTime(); Duration duration = new Duration(startTime, endTime); Period period = duration.toPeriod().normalizedStandard(PeriodType.time()); System.out.println(PeriodFormat.getDefault().print(period));

Quiero registrar la hora usando System.currentTimeMillis() cuando un usuario comienza algo en mi programa. Cuando termine, restaré el System.currentTimeMillis() actual de la variable de start , y quiero mostrarles el tiempo transcurrido usando un formato legible por el hombre como "XX horas, XX minutos, XX segundos" o incluso "XX minutos , XX segundos "porque no es probable que tome a alguien una hora.

¿Cuál es la mejor manera de hacer esto?


Aquí hay una respuesta basada en la respuesta de Brent Nash, ¡Espero que ayude!

public static String getDurationBreakdown(long millis) { String[] units = {" Days ", " Hours ", " Minutes ", " Seconds "}; Long[] values = new Long[units.length]; if(millis < 0) { throw new IllegalArgumentException("Duration must be greater than zero!"); } values[0] = TimeUnit.MILLISECONDS.toDays(millis); millis -= TimeUnit.DAYS.toMillis(values[0]); values[1] = TimeUnit.MILLISECONDS.toHours(millis); millis -= TimeUnit.HOURS.toMillis(values[1]); values[2] = TimeUnit.MILLISECONDS.toMinutes(millis); millis -= TimeUnit.MINUTES.toMillis(values[2]); values[3] = TimeUnit.MILLISECONDS.toSeconds(millis); StringBuilder sb = new StringBuilder(64); boolean startPrinting = false; for(int i = 0; i < units.length; i++){ if( !startPrinting && values[i] != 0) startPrinting = true; if(startPrinting){ sb.append(values[i]); sb.append(units[i]); } } return(sb.toString()); }


Basándome en la respuesta de @ siddhadev, escribí una función que convierte milisegundos en una cadena formateada:

/** * Convert a millisecond duration to a string format * * @param millis A duration to convert to a string form * @return A string of the form "X Days Y Hours Z Minutes A Seconds". */ public static String getDurationBreakdown(long millis) { if(millis < 0) { throw new IllegalArgumentException("Duration must be greater than zero!"); } 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(" Days "); sb.append(hours); sb.append(" Hours "); sb.append(minutes); sb.append(" Minutes "); sb.append(seconds); sb.append(" Seconds"); return(sb.toString()); }


Creo que la mejor manera es:

String.format("%d min, %d sec", TimeUnit.MILLISECONDS.toSeconds(length)/60, TimeUnit.MILLISECONDS.toSeconds(length) % 60 );


Esta respuesta es similar a algunas respuestas anteriores. Sin embargo, creo que sería beneficioso porque, a diferencia de otras respuestas, esto eliminará cualquier coma adicional o espacio en blanco y manejará la abreviatura.

/** * Converts milliseconds to "x days, x hours, x mins, x secs" * * @param millis * The milliseconds * @param longFormat * {@code true} to use "seconds" and "minutes" instead of "secs" and "mins" * @return A string representing how long in days/hours/minutes/seconds millis is. */ public static String millisToString(long millis, boolean longFormat) { if (millis < 1000) { return String.format("0 %s", longFormat ? "seconds" : "secs"); } String[] units = { "day", "hour", longFormat ? "minute" : "min", longFormat ? "second" : "sec" }; long[] times = new long[4]; times[0] = TimeUnit.DAYS.convert(millis, TimeUnit.MILLISECONDS); millis -= TimeUnit.MILLISECONDS.convert(times[0], TimeUnit.DAYS); times[1] = TimeUnit.HOURS.convert(millis, TimeUnit.MILLISECONDS); millis -= TimeUnit.MILLISECONDS.convert(times[1], TimeUnit.HOURS); times[2] = TimeUnit.MINUTES.convert(millis, TimeUnit.MILLISECONDS); millis -= TimeUnit.MILLISECONDS.convert(times[2], TimeUnit.MINUTES); times[3] = TimeUnit.SECONDS.convert(millis, TimeUnit.MILLISECONDS); StringBuilder s = new StringBuilder(); for (int i = 0; i < 4; i++) { if (times[i] > 0) { s.append(String.format("%d %s%s, ", times[i], units[i], times[i] == 1 ? "" : "s")); } } return s.toString().substring(0, s.length() - 2); } /** * Converts milliseconds to "x days, x hours, x mins, x secs" * * @param millis * The milliseconds * @return A string representing how long in days/hours/mins/secs millis is. */ public static String millisToString(long millis) { return millisToString(millis, false); }


Esto es más fácil en Java 9:

Duration elapsedTime = Duration.ofMillis(millisDiff ); String humanReadableElapsedTime = String.format( "%d hours, %d mins, %d seconds", elapsedTime.toHours(), elapsedTime.toMinutesPart(), elapsedTime.toSecondsPart());

Esto produce una cadena como 0 hours, 39 mins, 9 seconds .

Si quieres redondear a segundos enteros antes de formatear:

elapsedTime = elapsedTime.plusMillis(500).truncatedTo(ChronoUnit.SECONDS);

Dejar fuera las horas si son 0:

long hours = elapsedTime.toHours(); String humanReadableElapsedTime; if (hours == 0) { humanReadableElapsedTime = String.format( "%d mins, %d seconds", elapsedTime.toMinutesPart(), elapsedTime.toSecondsPart()); } else { humanReadableElapsedTime = String.format( "%d hours, %d mins, %d seconds", hours, elapsedTime.toMinutesPart(), elapsedTime.toSecondsPart()); }

Ahora podemos tener, por ejemplo, 39 mins, 9 seconds .

Para imprimir minutos y segundos con el cero inicial para convertirlos siempre en dos dígitos, simplemente inserte 02 en los especificadores de formato relevantes, por lo tanto:

String humanReadableElapsedTime = String.format( "%d hours, %02d mins, %02d seconds", elapsedTime.toHours(), elapsedTime.toMinutesPart(), elapsedTime.toSecondsPart());

Ahora podemos tener por ejemplo 0 hours, 39 mins, 09 seconds .


Hay un problema. Cuando los milisegundos son 59999, en realidad es 1 minuto, pero se calculará como 59 segundos y se perderán 999 milisegundos.

Aquí hay una versión modificada basada en respuestas anteriores, que puede resolver esta pérdida:

public static String formatTime(long millis) { long seconds = Math.round((double) millis / 1000); long hours = TimeUnit.SECONDS.toHours(seconds); if (hours > 0) seconds -= TimeUnit.HOURS.toSeconds(hours); long minutes = seconds > 0 ? TimeUnit.SECONDS.toMinutes(seconds) : 0; if (minutes > 0) seconds -= TimeUnit.MINUTES.toSeconds(minutes); return hours > 0 ? String.format("%02d:%02d:%02d", hours, minutes, seconds) : String.format("%02d:%02d", minutes, seconds); }


He cubierto esto en otra answer pero puedes hacer:

public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) { long diffInMillies = date2.getTime() - date1.getTime(); List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class)); Collections.reverse(units); Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>(); long milliesRest = diffInMillies; for ( TimeUnit unit : units ) { long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS); long diffInMilliesForUnit = unit.toMillis(diff); milliesRest = milliesRest - diffInMilliesForUnit; result.put(unit,diff); } return result; }

La salida es algo como Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0} , con las unidades ordenadas.

Depende de usted descubrir cómo internacionalizar estos datos de acuerdo con la configuración regional de destino.


Mi cálculo simple:

String millisecToTime(int millisec) { int sec = millisec/1000; int second = sec % 60; int minute = sec / 60; if (minute >= 60) { int hour = minute / 60; minute %= 60; return hour + ":" + (minute < 10 ? "0" + minute : minute) + ":" + (second < 10 ? "0" + second : second); } return minute + ":" + (second < 10 ? "0" + second : second); }

Feliz codificacion :)


Modifiqué la respuesta de @MyKuLLSKI y agregué soporte de plurlización. Saqué segundos porque no los necesitaba, aunque siéntase libre de volver a agregarlos si los necesita.

public static String intervalToHumanReadableTime(int intervalMins) { if(intervalMins <= 0) { return "0"; } else { long intervalMs = intervalMins * 60 * 1000; long days = TimeUnit.MILLISECONDS.toDays(intervalMs); intervalMs -= TimeUnit.DAYS.toMillis(days); long hours = TimeUnit.MILLISECONDS.toHours(intervalMs); intervalMs -= TimeUnit.HOURS.toMillis(hours); long minutes = TimeUnit.MILLISECONDS.toMinutes(intervalMs); StringBuilder sb = new StringBuilder(12); if (days >= 1) { sb.append(days).append(" day").append(pluralize(days)).append(", "); } if (hours >= 1) { sb.append(hours).append(" hour").append(pluralize(hours)).append(", "); } if (minutes >= 1) { sb.append(minutes).append(" minute").append(pluralize(minutes)); } else { sb.delete(sb.length()-2, sb.length()-1); } return(sb.toString()); } } public static String pluralize(long val) { return (Math.round(val) > 1 ? "s" : ""); }


No obtendría la dependencia adicional solo para eso (la división no es tan difícil, después de todo), pero si está utilizando Commons Lang de todos modos, existen los DurationFormatUtils .


O divisiones manuales, o utilice la API SimpleDateFormat .

long start = System.currentTimeMillis(); // do your work... long elapsed = System.currentTimeMillis() - start; DateFormat df = new SimpleDateFormat("HH ''hours'', mm ''mins,'' ss ''seconds''"); df.setTimeZone(TimeZone.getTimeZone("GMT+0")); System.out.println(df.format(new Date(elapsed)));

Edit by : se ha demostrado en los comentarios que este enfoque solo funciona para duraciones menores (es decir, menos de un día).


Para tiempos pequeños, menos de una hora, prefiero:

long millis = ... System.out.printf("%1$TM:%1$TS", millis); // or String str = String.format("%1$TM:%1$TS", millis);

para intervalos más largos:

private static final long HOUR = TimeUnit.HOURS.toMillis(1); ... if (millis < HOUR) { System.out.printf("%1$TM:%1$TS%n", millis); } else { System.out.printf("%d:%2$TM:%2$TS%n", millis / HOUR, millis % HOUR); }


Revisando la contribución de @ brent-nash, podríamos usar la función de módulo en lugar de sustracciones y usar el método String.format para la cadena de resultados:

/** * Convert a millisecond duration to a string format * * @param millis A duration to convert to a string form * @return A string of the form "X Days Y Hours Z Minutes A Seconds B Milliseconds". */ public static String getDurationBreakdown(long millis) { if (millis < 0) { throw new IllegalArgumentException("Duration must be greater than zero!"); } long days = TimeUnit.MILLISECONDS.toDays(millis); long hours = TimeUnit.MILLISECONDS.toHours(millis) % 24; long minutes = TimeUnit.MILLISECONDS.toMinutes(millis) % 60; long seconds = TimeUnit.MILLISECONDS.toSeconds(millis) % 60; long milliseconds = millis % 1000; return String.format("%d Days %d Hours %d Minutes %d Seconds %d Milliseconds", days, hours, minutes, seconds, milliseconds); }


Si sabe que la diferencia horaria sería menos de una hora, puede usar el siguiente código:

Calendar c1 = Calendar.getInstance(); Calendar c2 = Calendar.getInstance(); c2.add(Calendar.MINUTE, 51); long diff = c2.getTimeInMillis() - c1.getTimeInMillis(); c2.set(Calendar.MINUTE, 0); c2.set(Calendar.HOUR, 0); c2.set(Calendar.SECOND, 0); DateFormat df = new SimpleDateFormat("mm:ss"); long diff1 = c2.getTimeInMillis() + diff; System.out.println(df.format(new Date(diff1)));

Resultará a: 51:00


Solo para agregar más información si desea formatear como: HH: mm: ss

0 <= HH <= infinito

0 <= mm <60

0 <= ss <60

utilizar esta:

int h = (int) ((startTimeInMillis / 1000) / 3600); int m = (int) (((startTimeInMillis / 1000) / 60) % 60); int s = (int) ((startTimeInMillis / 1000) % 60);

Acabo de tener este problema ahora y resolví esto


Uhm ... ¿cuántos milisegundos hay en un segundo? ¿Y en un minuto? La división no es tan difícil.

int seconds = (int) ((milliseconds / 1000) % 60); int minutes = (int) ((milliseconds / 1000) / 60);

Continúa así por horas, días, semanas, meses, años, décadas, lo que sea.


Usando el paquete java.time en Java 8:

Instant start = Instant.now(); Thread.sleep(63553); Instant end = Instant.now(); System.out.println(Duration.between(start, end));

La salida está en ISO 8601 Formato de duración : PT1M3.553S (1 minuto y 3.553 segundos).


Use java.util.concurrent.TimeUnit, y use este método simple:

private static long timeDiff(Date date, Date date2, TimeUnit unit) { long milliDiff=date2.getTime()-date.getTime(); long unitDiff = unit.convert(milliDiff, TimeUnit.MILLISECONDS); return unitDiff; }

Por ejemplo:

SimpleDateFormat sdf = new SimpleDateFormat("yy/MM/dd HH:mm:ss"); Date firstDate = sdf.parse("06/24/2017 04:30:00"); Date secondDate = sdf.parse("07/24/2017 05:00:15"); Date thirdDate = sdf.parse("06/24/2017 06:00:15"); System.out.println("days difference: "+timeDiff(firstDate,secondDate,TimeUnit.DAYS)); System.out.println("hours difference: "+timeDiff(firstDate,thirdDate,TimeUnit.HOURS)); System.out.println("minutes difference: "+timeDiff(firstDate,thirdDate,TimeUnit.MINUTES)); System.out.println("seconds difference: "+timeDiff(firstDate,thirdDate,TimeUnit.SECONDS));


Use la clase java.util.concurrent.TimeUnit :

String.format("%d min, %d sec", TimeUnit.MILLISECONDS.toMinutes(millis), TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)) );

Nota: TimeUnit es parte de la especificación Java 1.5, pero toMinutes se agregó a partir de Java 1.6.

Para agregar un cero inicial para los valores 0-9, simplemente haga:

String.format("%02d min, %02d sec", TimeUnit.MILLISECONDS.toMinutes(millis), TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)) );

Si TimeUnit o toMinutes no son compatibles (como en Android antes de la versión 9 de la API), use las siguientes ecuaciones:

int seconds = (int) (milliseconds / 1000) % 60 ; int minutes = (int) ((milliseconds / (1000*60)) % 60); int hours = (int) ((milliseconds / (1000*60*60)) % 24); //etc...


para Android debajo de API 9

(String.format("%d hr %d min, %d sec", millis/(1000*60*60), (millis%(1000*60*60))/(1000*60), ((millis%(1000*60*60))%(1000*60))/1000))


para las cadenas correctas ("1 hora, 3 segundos", "3 minutos" pero no "0 horas, 0 minutos, 3 segundos") escribo este código:

int seconds = (int)(millis / 1000) % 60 ; int minutes = (int)((millis / (1000*60)) % 60); int hours = (int)((millis / (1000*60*60)) % 24); int days = (int)((millis / (1000*60*60*24)) % 365); int years = (int)(millis / 1000*60*60*24*365); ArrayList<String> timeArray = new ArrayList<String>(); if(years > 0) timeArray.add(String.valueOf(years) + "y"); if(days > 0) timeArray.add(String.valueOf(days) + "d"); if(hours>0) timeArray.add(String.valueOf(hours) + "h"); if(minutes>0) timeArray.add(String.valueOf(minutes) + "min"); if(seconds>0) timeArray.add(String.valueOf(seconds) + "sec"); String time = ""; for (int i = 0; i < timeArray.size(); i++) { time = time + timeArray.get(i); if (i != timeArray.size() - 1) time = time + ", "; } if (time == "") time = "0 sec";


La solución más corta:

Aquí es probablemente el más corto que también se ocupa de las zonas horarias.

System.out.printf("%tT", millis-TimeZone.getDefault().getRawOffset());

Que salidas por ejemplo:

00:18:32

Explicación:

%tT es la hora formateada para el reloj de 24 horas como %tH:%tM:%tS .

%tT también acepta largos como entrada, por lo que no es necesario crear una Date . printf() simplemente imprimirá la hora especificada en milisegundos, pero en la zona horaria actual, por lo tanto, tenemos que restar el desplazamiento bruto de la zona horaria actual para que 0 milisegundos sean 0 horas y no el valor de compensación de hora de la zona horaria actual .

Nota # 1: Si necesita el resultado como una String , puede obtenerlo así:

String t = String.format("%tT", millis-TimeZone.getDefault().getRawOffset());

Nota # 2: Esto solo da un resultado correcto si millis es menos de un día porque la parte del día no está incluida en la salida.


long startTime = System.currentTimeMillis(); // do your work... long endTime=System.currentTimeMillis(); long diff=endTime-startTime; long hours=TimeUnit.MILLISECONDS.toHours(diff); diff=diff-(hours*60*60*1000); long min=TimeUnit.MILLISECONDS.toMinutes(diff); diff=diff-(min*60*1000); long seconds=TimeUnit.MILLISECONDS.toSeconds(diff); //hour, min and seconds variables contains the time elapsed on your work


long time = 1536259; return (new SimpleDateFormat("mm:ss:SSS")).format(new Date(time));

Huellas dactilares:

25: 36: 259