Me gustaría formatear una duración en segundos usando un patrón como H:MM:SS. Las utilidades actuales en Java están diseñadas para formatear una hora pero no una duración.
¿Cómo formatear una duración en java? (por ejemplo, formato H:MM:SS)
bobince
Si no desea arrastrar bibliotecas, es lo suficientemente simple como para hacerlo usted mismo usando un Formateador o un atajo relacionado, por ejemplo. número entero dado de segundos s:
String.format("%d:%02d:%02d", s / 3600, (s % 3600) / 60, (s % 60));
-
No tiene que ser entero. Si tiene dos fechas, simplemente conecte date1.getTime() – date2.getTime() en la ecuación anterior que usa la primitiva larga y aún funciona.
– José
5 de noviembre de 2008 a las 22:51
-
¿Qué pasa si la diferencia horaria es mayor a 24h?
– Rajish
15 de julio de 2011 a las 9:43
-
@Rajish: ¡tendrías que preguntarle al OP qué querían en ese caso! Por supuesto que puedes separarlo en
s/86400, (s%86400)/3600...
por dias si es necesario…– bobince
15 de julio de 2011 a las 20:37
-
mi solución a
s > 8640
0 (un día):"\u221E"
– infinito– QED
23 de agosto de 2012 a las 23:21
-
Si la diferencia horaria es de más de 24 horas, igual formatea bien la duración en horas, minutos y segundos. Para mi caso de uso, esto es como se esperaba.
– Audrius Meškauskas
29 de agosto de 2015 a las 16:31
gili nachum
yo uso apache common’s DuraciónFormatUtils al igual que:
DurationFormatUtils.formatDuration(millis, "**H:mm:ss**", true);
-
La forma más fácil posible (al estilo apache commons). Incluso tiene el método formatDurationHMS que probablemente usará la mayor parte del tiempo.
– Marco
28 de marzo de 2015 a las 22:06
-
¡Perfecto! También puede agregar otro texto dentro del apóstrofo: DurationFormatUtils.formatDuration(durationInMillis, “m ‘minutos’, s ‘segundos'”)
– mihca
18 de febrero de 2020 a las 16:21
jon skeet
Si está utilizando una versión de Java anterior a la 8… puede utilizar hora joda y PeriodFormatter
. Si realmente tiene una duración (es decir, una cantidad de tiempo transcurrido, sin referencia a un sistema de calendario), entonces probablemente debería usar Duration
en su mayor parte, luego puede llamar toPeriod
(especificando lo que sea PeriodType
desea reflejar si 25 horas se convierten en 1 día y 1 hora o no, etc.) para obtener una Period
que puede formatear.
Si está utilizando Java 8 o posterior: normalmente sugeriría usar java.time.Duration
para representar la duración. A continuación, puede llamar getSeconds()
o similar para obtener un número entero para el formato de cadena estándar según la respuesta de bobince si es necesario, aunque debe tener cuidado con la situación en la que la duración es negativa, ya que probablemente desee un único signo negativo en la cadena de salida. Entonces algo como:
public static String formatDuration(Duration duration) {
long seconds = duration.getSeconds();
long absSeconds = Math.abs(seconds);
String positive = String.format(
"%d:%02d:%02d",
absSeconds / 3600,
(absSeconds % 3600) / 60,
absSeconds % 60);
return seconds < 0 ? "-" + positive : positive;
}
Formatear de esta manera es razonablemente simple, aunque molestamente manual. Para analizando se convierte en un asunto más difícil en general … Todavía podría usar Joda Time incluso con Java 8 si lo desea, por supuesto.
-
¿Aún recomendaría usar la biblioteca Joda Time cuando use Java 8?
– Tim Büthe
04/08/2014 a las 17:20
-
@TimBüthe: No, comenzaría a usar java.time en ese caso. (Aunque no puedo encontrar inmediatamente un equivalente de PeriodFormatter…)
– Jon Skeet
4 de agosto de 2014 a las 17:27
-
PeriodFormatter no está incluido. Esa es una de las diferencias entre Java 8 Date Time API y Joda Time.
– Tim Büthe
04/08/2014 a las 17:33
-
@RexKerr: Bueno, todavía hay “usar Joda Time” si quieres, por supuesto. Editará de nuevo. (Mirando hacia atrás, debería haber estado recomendando Duration de todos modos, por lo que parece. Se requiere una edición significativa…)
– Jon Skeet
29/10/2015 a las 14:56
-
@MarkJeronimus Aún más fácil sería usar el
Duration
métodos:duration.toHours()
,duration.toMinutesPart()
yduration.toSecondsPart()
que están disponibles desde Java 9. Y para obtener el valor absoluto se puede usarduration.abs()
.– recke96
15 de junio de 2018 a las 17:25
Ole VV
Esto es más fácil desde Java 9. A Duration
todavía no se puede formatear, pero se agregan métodos para obtener las horas, los minutos y los segundos, lo que hace que la tarea sea un poco más sencilla:
LocalDateTime start = LocalDateTime.of(2019, Month.JANUARY, 17, 15, 24, 12);
LocalDateTime end = LocalDateTime.of(2019, Month.JANUARY, 18, 15, 43, 33);
Duration diff = Duration.between(start, end);
String hms = String.format("%d:%02d:%02d",
diff.toHours(),
diff.toMinutesPart(),
diff.toSecondsPart());
System.out.println(hms);
El resultado de este fragmento es:
24:19:21
long duration = 4 * 60 * 60 * 1000;
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault());
log.info("Duration: " + sdf.format(new Date(duration - TimeZone.getDefault().getRawOffset())));
-
¡Ja! Simplemente golpee la pared con la normalización de la zona horaria cuando use este método. tienes que agregar
sdf.setTimeZone(TimeZone.getTimeZone("GMT+0"));
antes de usar elformat
función.– Rajish
15 de julio de 2011 a las 9:46
-
Se recomienda usar
DateFormat.getDateInstance()
en lugar de clases concretas.– Abhijit Sarkar
25 de julio de 2020 a las 10:58
-
Esta solución es frágil. Se volcará a
00:00:00.000
cuando el número de horas llega a 24h. Además, un segundo negativo se formatea como23:59:59.000
.– VS
12 de agosto de 2020 a las 8:00
ctg
Hay un enfoque bastante simple y (en mi opinión) elegante, al menos para duraciones de menos de 24 horas:
DateTimeFormatter.ISO_LOCAL_TIME.format(value.addTo(LocalTime.of(0, 0)))
Los formateadores necesitan un objeto temporal para formatear, por lo que puede crear uno agregando la duración a LocalTime de 00:00 (es decir, medianoche). Esto le dará un LocalTime que representa la duración desde la medianoche hasta ese momento, que luego es fácil de formatear en la notación estándar HH: mm: ss. Esto tiene la ventaja de no necesitar una biblioteca externa y utiliza la biblioteca java.time para realizar el cálculo, en lugar de calcular manualmente las horas, los minutos y los segundos.
-
¡Ja! Simplemente golpee la pared con la normalización de la zona horaria cuando use este método. tienes que agregar
sdf.setTimeZone(TimeZone.getTimeZone("GMT+0"));
antes de usar elformat
función.– Rajish
15 de julio de 2011 a las 9:46
-
Se recomienda usar
DateFormat.getDateInstance()
en lugar de clases concretas.– Abhijit Sarkar
25 de julio de 2020 a las 10:58
-
Esta solución es frágil. Se volcará a
00:00:00.000
cuando el número de horas llega a 24h. Además, un segundo negativo se formatea como23:59:59.000
.– VS
12 de agosto de 2020 a las 8:00
lauhub
Esta respuesta solo usa Duration
métodos y funciona con Java 8:
public static String format(Duration d) {
long days = d.toDays();
d = d.minusDays(days);
long hours = d.toHours();
d = d.minusHours(hours);
long minutes = d.toMinutes();
d = d.minusMinutes(minutes);
long seconds = d.getSeconds() ;
return
(days == 0?"":days+" jours,")+
(hours == 0?"":hours+" heures,")+
(minutes == 0?"":minutes+" minutes,")+
(seconds == 0?"":seconds+" secondes,");
}