Converter o valor dos segundos em horas, minutos, segundos?


109

Tenho tentado converter um valor de segundos (em uma variável BigDecimal) em uma string em um editText como "1 hora 22 minutos 33 segundos" ou algo do tipo.

Eu tentei isso:

String sequenceCaptureTime = "";
BigDecimal roundThreeCalc = new BigDecimal("0");
BigDecimal hours = new BigDecimal("0");
BigDecimal myremainder = new BigDecimal("0");
BigDecimal minutes = new BigDecimal("0");
BigDecimal seconds = new BigDecimal("0");
BigDecimal var3600 = new BigDecimal("3600");
BigDecimal var60 = new BigDecimal("60");

(Eu tenho um roundThreeCalc que é o valor em segundos, então tento convertê-lo aqui.)

hours = (roundThreeCalc.divide(var3600));
myremainder = (roundThreeCalc.remainder(var3600));
minutes = (myremainder.divide(var60));
seconds = (myremainder.remainder(var60));
sequenceCaptureTime =  hours.toString() + minutes.toString() + seconds.toString();

Em seguida, defino editText como sequnceCaptureTime String. Mas isso não funcionou. Ele forçou o fechamento do aplicativo todas as vezes. Estou totalmente perdido aqui, qualquer ajuda será muito apreciada. Boa codificação!



Alguma razão pela qual você está usando BigDecimal em vez de BigInteger?
Ted Hopp

Vou ter que implementar frações de segundo mais tarde no dev, agora estou apenas tentando fazer o cálculo funcionar em primeiro lugar.
coelhot

1
Apoio o comentário de Richard - você pode usar a enum TimeUnit para fazer muito do trabalho para você. developer.android.com/reference/java/util/concurrent/…
Ben J

Como eu usaria a unidade de tempo para converter de um BigDecimal com segundos para HHMMSS?
coelhot

Respostas:


65

Você deveria ter mais sorte com

hours = roundThreeCalc.divide(var3600, BigDecimal.ROUND_FLOOR);
myremainder = roundThreeCalc.remainder(var3600);
minutes = myremainder.divide(var60, BigDecimal.ROUND_FLOOR);
seconds = myremainder.remainder(var60);

Isso eliminará os valores decimais após cada divisão.

Edit: Se isso não funcionar, tente isso. (Acabei de escrever e testar)

public static int[] splitToComponentTimes(BigDecimal biggy)
{
    long longVal = biggy.longValue();
    int hours = (int) longVal / 3600;
    int remainder = (int) longVal - hours * 3600;
    int mins = remainder / 60;
    remainder = remainder - mins * 60;
    int secs = remainder;

    int[] ints = {hours , mins , secs};
    return ints;
}

6
Esta solução é mais elegante: stackoverflow.com/questions/625433/…
Alex Kucherenko

@AlexKucherenko exceto que a solução funciona com milissegundos
Mikhail

1
@Mikhail TimeUnit. #### permitirá que você faça isso com qualquer unidade de tempo.
Amir Omidi,

1
Sempre que você se pega fazendo matemática com valores de hora e data, precisa parar e encontrar a API certa no idioma em questão. Se você só precisa de uma resposta do tipo HH: MM: SS, ficará melhor com DateUtils.formatElapsedTime...
dovetalk

229

É necessário usar um BigDecimal? Se você não precisar, eu usaria um int ou long por segundos e isso simplificaria um pouco as coisas:

hours = totalSecs / 3600;
minutes = (totalSecs % 3600) / 60;
seconds = totalSecs % 60;

timeString = String.format("%02d:%02d:%02d", hours, minutes, seconds);

Você pode querer preencher cada um para ter certeza de que são valores de dois dígitos (ou qualquer outro) na string.


Vou ter que implementar frações de segundo mais tarde no dev, agora estou apenas tentando fazer o cálculo funcionar em primeiro lugar.
coelhot

13
String.format("%02d:%02d:%02d", hours, minutes, seconds);
Jeffrey Blattman

Isso é simplesmente impressionante. Eu me pergunto como o módulo pode funcionar dessa maneira.
PSo

Use Locale, caso contrário, ele avisará. String.format(Locale.ENGLISH, "%02d:%02d:%02d", hours, minutes, seconds)
Pratik Butani

1
Sempre que você se pega fazendo matemática com valores de hora e data, precisa parar e encontrar a API certa no idioma em questão. Se você só precisa de uma resposta do tipo HH: MM: SS, ficará melhor com DateUtils.formatElapsedTime...
dovetalk

75

DateUtils.formatElapsedTime(long), formata um tempo decorrido no formato " MM:SS" ou " H:MM:SS". Ele retorna a String que você está procurando. Você pode encontrar a documentação aqui


3
Este é simples e exatamente o que eu preciso. Eu recomendo a outros este método
Nabin

1
Não se esqueça de que ele espera parâmetro em segundos. Portanto, você precisa converter milis para segundos
kirank

28

Aqui está o código de trabalho:

private String getDurationString(int seconds) {

    int hours = seconds / 3600;
    int minutes = (seconds % 3600) / 60;
    seconds = seconds % 60;

    return twoDigitString(hours) + " : " + twoDigitString(minutes) + " : " + twoDigitString(seconds);
}

private String twoDigitString(int number) {

    if (number == 0) {
        return "00";
    }

    if (number / 10 == 0) {
        return "0" + number;
    }

    return String.valueOf(number);
}

3
Eu gosto desta resposta, mas você precisa alterar '% 10' para '/ 10'
Hakem Zaied

Sempre que você se pega fazendo matemática com valores de hora e data, precisa parar e encontrar a API certa no idioma em questão. Se você só precisa de uma resposta do tipo HH: MM: SS, ficará melhor com DateUtils.formatElapsedTime...
dovetalk

28

Algo realmente útil em Java 8

import java.time.LocalTime;

private String ConvertSecondToHHMMSSString(int nSecondTime) {
    return LocalTime.MIN.plusSeconds(nSecondTime).toString();
}

Nota: O cálculo ocorre em torno da meia-noite ao usar maisSegundos (segundos longos), por exemplo: se segundos for 86400 (24 horas), a saída será 00:00.
karthi

Ele faz exatamente o que o nome sugere 'ConvertSecondToHHMMSSString'. As outras soluções (tediosas) também estão surgindo.
Epicuro de

@Epicurist essa era a solução que eu procurava! Muito mais elegante do que todos os outros! :)
Paulo Oliveira

20

Eu prefiro a biblioteca TimeUnit do java

long seconds = TimeUnit.MINUTES.toSeconds(8);

12
private String ConvertSecondToHHMMString(int secondtTime)
{
  TimeZone tz = TimeZone.getTimeZone("UTC");
  SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
  df.setTimeZone(tz);
  String time = df.format(new Date(secondtTime*1000L));

  return time;

}

Você poderia melhorar ainda mais sua resposta explicando o que o código faz e como ele resolve o problema ;-)
2Dee

9

Esta é minha solução simples:

String secToTime(int sec) {
    int seconds = sec % 60;
    int minutes = sec / 60;
    if (minutes >= 60) {
        int hours = minutes / 60;
        minutes %= 60;
        if( hours >= 24) {
            int days = hours / 24;
            return String.format("%d days %02d:%02d:%02d", days,hours%24, minutes, seconds);
        }
        return String.format("%02d:%02d:%02d", hours, minutes, seconds);
    }
    return String.format("00:%02d:%02d", minutes, seconds);
}

Test Results:

Result: 00:00:36 - 36
Result: 01:00:07 - 3607
Result: 6313 days 12:39:05 - 545488745

6

Eu gosto de manter as coisas simples, portanto:

    int tot_seconds = 5000;
    int hours = tot_seconds / 3600;
    int minutes = (tot_seconds % 3600) / 60;
    int seconds = tot_seconds % 60;

    String timeString = String.format("%02d Hour %02d Minutes %02d Seconds ", hours, minutes, seconds);

    System.out.println(timeString);

O resultado será: 01 hora 23 minutos e 20 segundos


resposta mais curta, incrível
Kaveh Garshasp

5

Se você quiser as unidades h, mine secpor um período, você pode usar isto:

public static String convertSeconds(int seconds) {
    int h = seconds/ 3600;
    int m = (seconds % 3600) / 60;
    int s = seconds % 60;
    String sh = (h > 0 ? String.valueOf(h) + " " + "h" : "");
    String sm = (m < 10 && m > 0 && h > 0 ? "0" : "") + (m > 0 ? (h > 0 && s == 0 ? String.valueOf(m) : String.valueOf(m) + " " + "min") : "");
    String ss = (s == 0 && (h > 0 || m > 0) ? "" : (s < 10 && (h > 0 || m > 0) ? "0" : "") + String.valueOf(s) + " " + "sec");
    return sh + (h > 0 ? " " : "") + sm + (m > 0 ? " " : "") + ss;
}

int seconds = 3661;
String duration = convertSeconds(seconds);

São muitos operadores condicionais. O método retornará essas strings:

0    -> 0 sec
5    -> 5 sec
60   -> 1 min
65   -> 1 min 05 sec
3600 -> 1 h
3601 -> 1 h 01 sec
3660 -> 1 h 01
3661 -> 1 h 01 min 01 sec
108000 -> 30 h

Boa solução (Y)
Akshay Raiyani

4

Este código está funcionando bem:

txtTimer.setText(String.format("%02d:%02d:%02d",(SecondsCounter/3600), ((SecondsCounter % 3600)/60), (SecondsCounter % 60)));

4

Uma maneira fácil e agradável de fazer isso usando GregorianCalendar

Importe-os para o projeto:

import java.util.GregorianCalendar;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Scanner;

E depois:

Scanner s = new Scanner(System.in);

System.out.println("Seconds: ");
int secs = s.nextInt();

GregorianCalendar cal = new GregorianCalendar(0,0,0,0,0,secs);
Date dNow = cal.getTime();
SimpleDateFormat ft = new SimpleDateFormat("HH 'hours' mm 'minutes' ss 'seconds'");
System.out.println("Your time: " + ft.format(dNow));

1
Eu amo este!
eduyayo

2

Eu uso isso:

 public String SEG2HOR( long lnValue) {     //OK
        String lcStr = "00:00:00";
        String lcSign = (lnValue>=0 ? " " : "-");
        lnValue = lnValue * (lnValue>=0 ? 1 : -1); 

        if (lnValue>0) {                
            long lnHor  = (lnValue/3600);
            long lnHor1 = (lnValue % 3600);
            long lnMin  = (lnHor1/60);
            long lnSec  = (lnHor1 % 60);            

                        lcStr = lcSign + ( lnHor < 10 ? "0": "") + String.valueOf(lnHor) +":"+
                              ( lnMin < 10 ? "0": "") + String.valueOf(lnMin) +":"+
                              ( lnSec < 10 ? "0": "") + String.valueOf(lnSec) ;
        }

        return lcStr;           
    }

2

Esta é minha função para resolver o problema:

public static String getConvertedTime(double time){

    double h,m,s,mil;

    mil = time % 1000;
    s = time/1000;
    m = s/60;
    h = m/60;
    s = s % 60;
    m = m % 60;
    h = h % 24;

    return ((int)h < 10 ? "0"+String.valueOf((int)h) : String.valueOf((int)h))+":"+((int)m < 10 ? "0"+String.valueOf((int)m) : String.valueOf((int)m))
            +":"+((int)s < 10 ? "0"+String.valueOf((int)s) : String.valueOf((int)s))
            +":"+((int)mil > 100 ? String.valueOf((int)mil) : (int)mil > 9 ? "0"+String.valueOf((int)mil) : "00"+String.valueOf((int)mil));
}

Por que esse jeito infantil de usar variáveis ​​de tipo duplo para armazenar os ints necessários?
Epicuro

2

Eu sei que isso é muito antigo, mas em java 8:

LocalTime.MIN.plusSeconds(120).format(DateTimeFormatter.ISO_LOCAL_TIME)

2

por apenas alguns minutos e segundos, use isso

String.format("%02d:%02d", (seconds / 3600 * 60 + ((seconds % 3600) / 60)), (seconds % 60))

1

Eu uso isso em python para converter um float que representa segundos em horas, minutos, segundos e microssegundos. É razoavelmente elegante e útil para converter para um tipo datetime por meio do strptime. Também pode ser facilmente estendido para intervalos maiores (semanas, meses, etc.), se necessário.

    def sectohmsus(seconds):
        x = seconds
        hmsus = []
        for i in [3600, 60, 1]:  # seconds in a hour, minute, and second
            hmsus.append(int(x / i))
            x %= i
        hmsus.append(int(round(x * 1000000)))  # microseconds
        return hmsus  # hours, minutes, seconds, microsecond

1

Eu tentei da melhor maneira e menos código, mas pode ser um pouco difícil de entender como eu escrevi meu código, mas se você é bom em matemática é tão fácil

import java.util.Scanner;

horas de aula {

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    double s;


    System.out.println("how many second you have ");
    s =input.nextInt();



     double h=s/3600;
     int h2=(int)h;

     double h_h2=h-h2;
     double m=h_h2*60;
     int m1=(int)m;

     double m_m1=m-m1;
     double m_m1s=m_m1*60;






     System.out.println(h2+" hours:"+m1+" Minutes:"+Math.round(m_m1s)+" seconds");





}

}

mais sobre isso é preciso!


1

Com o Java 8, você pode facilmente obter tempo no formato String de longos segundos como,

LocalTime.ofSecondOfDay(86399L)

Aqui, o valor fornecido tem permissão máxima para conversão (até 24 horas) e o resultado será

23:59:59

Prós: 1) Não há necessidade de converter manualmente e acrescentar 0 para um único dígito

Contras: trabalhar apenas por até 24 horas


1

Com o Java 8, você pode facilmente obter tempo no formato LocalTime em longos segundos, como

LocalTime.ofSecondOfDay(86399L)

Aqui, o valor fornecido tem permissão máxima para conversão (até 24 horas) e o resultado será

23:59:59

Prós: 1) Não há necessidade de converter manualmente e acrescentar 0 para um único dígito

Contras: trabalhar apenas por até 24 horas


1

Duração de java.time

    BigDecimal secondsValue = BigDecimal.valueOf(4953);
    if (secondsValue.compareTo(BigDecimal.valueOf(Long.MAX_VALUE)) > 0) {
        System.out.println("Seconds value " + secondsValue + " is out of range");
    } else {
        Duration dur = Duration.ofSeconds(secondsValue.longValueExact());
        long hours = dur.toHours();
        int minutes = dur.toMinutesPart();
        int seconds = dur.toSecondsPart();

        System.out.format("%d hours %d minutes %d seconds%n", hours, minutes, seconds);
    }

A saída deste snippet é:

1 hora 22 minutos 33 segundos

Se houvesse uma fração de segundo diferente de zero no BigDecimalcódigo, esse código não funcionaria como está, mas você poderá modificá-lo. O código funciona em Java 9 e posterior. Em Java 8, a conversão de Durationhoras, minutos e segundos é um pouco mais prolixa, consulte o link na parte inferior para saber como. Estou deixando para você escolher a forma correta de singular ou plural das palavras ( hora ou horas , etc.).

Links

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.