Quiero registrar el tiempo usando System.currentTimeMillis()
cuando un usuario comienza algo en mi programa. Cuando termine, restaré la corriente System.currentTimeMillis()
de la start
variable y quiero mostrarles el tiempo transcurrido utilizando un formato legible para humanos, como "XX horas, XX minutos, XX segundos" o incluso "XX minutos, XX segundos" porque No es probable que le tome a alguien una hora.
¿Cuál es la mejor manera de hacer esto?
Respuestas:
Usa la
java.util.concurrent.TimeUnit
clase:Nota:
TimeUnit
es parte de la especificación Java 1.5, perotoMinutes
se agregó a partir de Java 1.6.Para agregar un cero inicial para los valores 0-9, simplemente haga:
Si
TimeUnit
otoMinutes
no son compatibles (como en Android antes de la versión 9 de API), use las siguientes ecuaciones:fuente
int hours = (int) ((milliseconds / (1000*60*60)) % 24)
esto no funciona! en cambio debería ser asíint hours = (int) (milliseconds / (1000*60*60)) ;
String.format("%01d:%02d:%02d", hours, minutes, seconds);
Basado en la respuesta de @ siddhadev, escribí una función que convierte milisegundos a una cadena formateada:
fuente
1 Days 1 Hours 1 Minutes 1 Seconds
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;
y también el método String.format:return String.format("%d Days %d Hours %d Minutes %d Seconds %d Milliseconds", days, hours, minutes, seconds, milliseconds);
Huellas dactilares:
fuente
Duration dur = new Duration(start, end);
long millis = dur.getMillis();
DateTimeFormat.forPattern("mm:ss:SSS").print(new DateTime(time));
o convierta la duración en un período que se pueda imprimir automáticamente con un JodaPeriodFormatter
. La conversión podría tener una pérdida de precisión si no fuera la cronología ISO. Suponga una duración representada por la variableduration
.Period period = duration.toPeriod().normalizedStandard(PeriodType.time());
PeriodFormat.getDefault().print(period))
La salida es impresionante: 1 segundo y 581 milisegundos, respondiendo la pregunta principal anterior.Uhm ... ¿cuántos milisegundos hay en un segundo? ¿Y en un minuto? La división no es tan difícil.
Continúe así durante horas, días, semanas, meses, años, décadas, lo que sea.
fuente
Usando el paquete java.time en Java 8:
La salida está en formato de duración ISO 8601 :
PT1M3.553S
(1 minuto y 3.553 segundos).fuente
No obtendría la dependencia adicional solo por eso (la división no es tan difícil, después de todo), pero si está utilizando Commons Lang de todos modos, están los DurationFormatUtils .
Ejemplo de uso (adaptado de aquí ):
Ejemplo:
Nota : Para obtener millis de dos objetos LocalDateTime, puede usar:
fuente
Divide a mano o usa la API SimpleDateFormat .
Editar por Bombe : Se ha demostrado en los comentarios que este enfoque solo funciona para duraciones más pequeñas (es decir, menos de un día).
fuente
Solo para agregar más información si desea formatear como: HH: mm: ss
0 <= HH <= infinito
0 <= mm <60
0 <= ss <60
utilizar este:
Acabo de tener este problema ahora y descubrí esto
fuente
Creo que la mejor manera es:
fuente
La solución más corta:
Aquí es probablemente el más corto que también se ocupa de las zonas horarias.
Qué salidas, por ejemplo:
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 unDate
.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 horaria de la zona horaria actual.Nota # 1: Si necesita el resultado como a
String
, puede obtenerlo así:Nota # 2: Esto solo da el resultado correcto si
millis
es menos de un día porque la parte del día no está incluida en la salida.fuente
long millis = 8398;
y cuando paso eso aString.format("%tT", millis)
mi salida es 19:00:08. ¿De dónde vienen los 19?TimeZone.getDefault().getRawOffset()
, exactamente como está escrito en la respuesta:String.format("%tT", millis-TimeZone.getDefault().getRawOffset())
Joda-Time
Usando Joda-Time :
fuente
PeriodFormat
en la última línea. Simplemente llamePeriod::toString
para obtener una cadena de duración ISO 8601 de forma predeterminada.Revisando la contribución @ 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 resultado:
fuente
para Android debajo de API 9
fuente
Para tiempos pequeños, menos de una hora, prefiero:
para intervalos más largos:
fuente
%tH
solo se muestra de 0 a 23 horas? Eso significa que, por ejemplo, 24 horas se mostrarán como00
, 25 horas como01
... lo mismo válido para%tT
- los días se descartarán en silencio. Claro, también podría mostrar días, pero eso sería una exageración para el problema que tuve cuando escribí esto (en 2011) [:-)Mi simple cálculo:
Feliz codificación :)
fuente
Aquí hay una respuesta basada en la respuesta de Brent Nash, ¡espero que ayude!
fuente
fuente
diff=diff-(hours*60*1000);
debería serdiff=diff-(hours*60*60*1000);
. Intenté editarlo, pero la molesta política de edición de StackOverflow dice que no hay suficientes caracteres para una edición.En primer lugar,
System.currentTimeMillis()
yInstant.now()
no son ideales para el tiempo. Ambos informan la hora del reloj de pared, que la computadora no conoce con precisión, y que puede moverse erráticamente, incluso retroceder si, por ejemplo, el demonio NTP corrige la hora del sistema. Si su sincronización ocurre en una sola máquina, entonces debería usar System.nanoTime () .En segundo lugar, desde Java 8 en adelante, java.time.Duration es la mejor manera de representar una duración:
fuente
Si sabe que la diferencia horaria sería inferior a una hora, puede usar el siguiente código:
Resultará a: 51:00
fuente
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 o espacio en blanco adicional y maneja la abreviatura.
fuente
Hay un problema. Cuando milisegundos es 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:
fuente
Esto es más fácil en Java 9:
Esto produce una cadena como
0 hours, 39 mins, 9 seconds
.Si desea redondear a segundos completos antes de formatear:
Para dejar fuera las horas si son 0:
Ahora podemos tener por ejemplo
39 mins, 9 seconds
.Para imprimir minutos y segundos con cero a la izquierda para que siempre tengan dos dígitos, simplemente inserte
02
en los especificadores de formato relevantes, de esta manera:Ahora podemos tener por ejemplo
0 hours, 39 mins, 09 seconds
.fuente
if
...else
allí.para las cadenas correctas ("1 hora, 3 segundos", "3 minutos" pero no "0 horas, 0 minutos, 3 segundos") escribo este código:
fuente
Modifiqué la respuesta de @MyKuLLSKI y agregué soporte de plurlización. Saqué segundos porque no los necesitaba, aunque siéntase libre de volver a agregarlo si lo necesita.
fuente
int intervalMins
vslong millis
He cubierto esto en otra respuesta pero puedes hacer:
La salida es algo así
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.
fuente
Use java.util.concurrent.TimeUnit y use este método simple:
Por ejemplo:
fuente
DurationFormatUtils.formatDurationHMS (largo)
fuente