Quero registrar o tempo System.currentTimeMillis()
em que um usuário inicia algo no meu programa. Quando ele terminar, subtrairei a corrente System.currentTimeMillis()
da start
variável e quero mostrar o tempo decorrido usando um formato legível por humanos, como "XX horas, XX minutos, XX segundos" ou mesmo "XX minutos, XX segundos", porque provavelmente não levará alguém por uma hora.
Qual é a melhor forma de fazer isso?
Respostas:
Use a
java.util.concurrent.TimeUnit
classe:Nota:
TimeUnit
faz parte da especificação Java 1.5, mastoMinutes
foi adicionado a partir do Java 1.6.Para adicionar um zero inicial para os valores de 0 a 9, faça o seguinte:
Se
TimeUnit
outoMinutes
não é suportado (como no Android antes da API versão 9), use as seguintes equações:fonte
int hours = (int) ((milliseconds / (1000*60*60)) % 24)
isso não funciona! em vez disso, deveria ser assimint hours = (int) (milliseconds / (1000*60*60)) ;
String.format("%01d:%02d:%02d", hours, minutes, seconds);
Com base na resposta de @ siddhadev, escrevi uma função que converte milissegundos em uma string formatada:
fonte
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;
e também método String.format:return String.format("%d Days %d Hours %d Minutes %d Seconds %d Milliseconds", days, hours, minutes, seconds, milliseconds);
Impressões:
fonte
Duration dur = new Duration(start, end);
long millis = dur.getMillis();
DateTimeFormat.forPattern("mm:ss:SSS").print(new DateTime(time));
ou converta a Duração em um Período que pode ser impresso automaticamente usando um JodaPeriodFormatter
. A conversão pode ter uma perda de precisão se não for a cronologia ISO. Suponha uma Duração representada pela variávelduration
.Period period = duration.toPeriod().normalizedStandard(PeriodType.time());
PeriodFormat.getDefault().print(period))
A produção é impressionante: 1 segundo e 581 milissegundos, respondendo à principal pergunta acima.Uhm ... quantos milissegundos existem em um segundo? E em um minuto? Divisão não é tão difícil.
Continue assim por horas, dias, semanas, meses, ano, décadas, o que for.
fonte
Usando o pacote java.time no Java 8:
A saída está no formato ISO 8601 Duration :
PT1M3.553S
(1 minuto e 3.553 segundos).fonte
Eu não extrairia a dependência extra apenas para isso (afinal, a divisão não é tão difícil), mas se você estiver usando o Commons Lang de qualquer maneira, há o DurationFormatUtils .
Exemplo de uso (adaptado daqui ):
Exemplo:
Nota : Para obter millis de dois objetos LocalDateTime, você pode usar:
fonte
Divisões manuais, ou use a API SimpleDateFormat .
Editar por Bombe : Foi demonstrado nos comentários que essa abordagem funciona apenas por períodos menores (ou seja, menos de um dia).
fonte
Apenas para adicionar mais informações, se você deseja formatar como: HH: mm: ss
0 <= HH <= infinito
0 <= mm <60
0 <= ss <60
usa isto:
Eu só tinha esse problema agora e descobri isso
fonte
Eu acho que a melhor maneira é:
fonte
Solução mais curta:
Aqui está provavelmente o mais curto, que também lida com fusos horários.
Quais saídas, por exemplo:
Explicação:
%tT
é a hora formatada para o relógio de 24 horas como%tH:%tM:%tS
.%tT
também aceita longs como entrada, portanto, não há necessidade de criar umDate
.printf()
simplesmente imprimirá a hora especificada em milissegundos, mas no fuso horário atual, portanto, temos que subtrair o deslocamento bruto do fuso horário atual para que 0 milissegundos sejam 0 horas e não o valor do deslocamento de hora do fuso horário atual.Nota 1: se você precisar do resultado como a
String
, poderá obtê-lo assim:Nota 2: Isso só fornece resultado correto se
millis
for menor que um dia, porque a parte do dia não está incluída na saída.fonte
long millis = 8398;
e quando passo isso para aString.format("%tT", millis)
minha saída é 19:00:08. De onde vêm os 19?TimeZone.getDefault().getRawOffset()
-lo, exatamente como está escrito na resposta:String.format("%tT", millis-TimeZone.getDefault().getRawOffset())
Joda-Time
Usando Joda-Time :
fonte
PeriodFormat
na última linha. Basta ligarPeriod::toString
para obter uma sequência de duração ISO 8601 por padrão.Revisitando a contribuição @ brent-nash, poderíamos usar a função de módulo em vez de subtrações e usar o método String.format para a sequência de resultados:
fonte
para Android abaixo da API 9
fonte
Por tempos pequenos, menos de uma hora, prefiro:
para intervalos mais longos:
fonte
%tH
apenas de 0 a 23 horas? Isso significa que, por exemplo, 24 horas seriam exibidas como00
, 25 horas como01
... mesmas válidas por%tT
- dias serão descartadas silenciosamente. Claro, também pode ter dias exibida, mas isso seria um exagero para o problema que eu tive quando eu escrevi isso (de volta em 2011) [:-)Meu cálculo simples:
Feliz codificação :)
fonte
Aqui está uma resposta baseada na resposta de Brent Nash, Espero que ajude!
fonte
fonte
diff=diff-(hours*60*1000);
deveria serdiff=diff-(hours*60*60*1000);
. Tentei editá-lo, mas a política de edição irritante do StackOverflow diz que não há caracteres suficientes para uma edição.Em primeiro lugar,
System.currentTimeMillis()
eInstant.now()
não são ideais para o tempo. Ambos relatam a hora do relógio de parede, que o computador não sabe com precisão e que pode se mover erraticamente, incluindo retroceder se, por exemplo, o daemon NTP corrigir a hora do sistema. Se o tempo ocorrer em uma única máquina, você deverá usar System.nanoTime () .Em segundo lugar, do Java 8 em diante, java.time.Duration é a melhor maneira de representar uma duração:
fonte
Se você souber que a diferença horária seria menor que uma hora, poderá usar o seguinte código:
O resultado será: 51:00
fonte
Esta resposta é semelhante a algumas respostas acima. No entanto, acho que seria benéfico porque, diferentemente de outras respostas, isso removerá qualquer vírgula ou espaço em branco extra e manipulará a abreviação.
fonte
Há um problema. Quando milissegundos é 59999, na verdade é 1 minuto, mas será calculado em 59 segundos e 999 milissegundos são perdidos.
Aqui está uma versão modificada com base nas respostas anteriores, que podem resolver essa perda:
fonte
Isso é mais fácil no Java 9:
Isso produz uma string como
0 hours, 39 mins, 9 seconds
.Se você deseja arredondar para segundos inteiros antes de formatar:
Para deixar de fora as horas, se forem 0:
Agora podemos ter, por exemplo
39 mins, 9 seconds
.Para imprimir minutos e segundos com zero à esquerda para torná-los sempre com dois dígitos, basta inserir
02
nos especificadores de formato relevantes, assim:Agora podemos ter, por exemplo
0 hours, 39 mins, 09 seconds
.fonte
if
-else
aí.para seqüências corretas ("1 hora, 3seg", "3 min", mas não "0 horas, 0 min, 3 seg"), escrevo este código:
fonte
Modifiquei a resposta de @MyKuLLSKI e adicionei suporte à plurlização. Demorei alguns segundos porque não precisava deles, mas fique à vontade para adicioná-lo novamente, se precisar.
fonte
int intervalMins
vslong millis
Eu cobri isso em outra resposta, mas você pode fazer:
A saída é algo como
Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}
, com as unidades encomendadas.Cabe a você descobrir como internacionalizar esses dados de acordo com o local de destino.
fonte
Use java.util.concurrent.TimeUnit e use este método simples:
Por exemplo:
fonte
DurationFormatUtils.formatDurationHMS (long)
fonte