How to subtract 2 hours string

Asked

Viewed 311 times

0

I’m doing a Java project in Android Studio where I have a database connected to a BD on a server.

In one of the tables, I have 2 hours, hora_inicio and hora_fim that are extracted to string.

I intend to subtract between them, ie, hora_fim - hora_inicio, but as they are of the type string and the hours have the : example, "14:20", I can’t make that subtraction.

I tried to convert to int, but the code gives error. How can I do to subtract?

My code:

 private void Escrever_Estatisticas(View mainlayout) {
        FormSolicitarViagem.obterDataHoraServidor();
        
       //vai buscar a data atual -> data
        Date data = new Date(FuncoesUTEIS.reduzirXDias(FormSolicitarViagem.getMinData().getTime(),1)); //data minima é data posterior ao dia atual
        String data_minima_estatisticas = data.toString().substring(0,7)+ "-01"; //extrai somente os primeiros caracteres da string -> temos ano e mes e adicionamos o dia

        LocalDataBase bd = new LocalDataBase(getContext());
        String sqlAndroid = "select * from viagens_condutor where estado = 2 and data_viagem >= '" + data_minima_estatisticas + "'"; //base de dados local do android -> só tem a pessoa em causa
        Cursor cursor = bd.executar_select(bd.dbr, sqlAndroid);
        cursor.moveToFirst();

        String Total_km = null;
        int totalKm = 0;
        int totalhoras = 0;
        String Total_horas_viagem = null;
        int nviagens=0;
        String num_viagens = null;
        while (!cursor.isAfterLast()) { //se não estiver na última posição
            String km = cursor.getString(3);
            // totalhoras_viagens = cursor.getString(6);
            int converterkm = Integer.parseInt(km);
            totalKm += converterkm;

            String hora_inicio = cursor.getString(10);
            Log.e("in", hora_inicio);
            String hora_fim = cursor.getString(11);
            Log.e("out", hora_fim);
            //int converter_hora_inicio = Integer.parseInt(hora_inicio);
            //int converter_hora_fim = Integer.parseInt(hora_fim);

            nviagens+=1;

            cursor.moveToNext();
        }

2 answers

3

An alternative is to use the API java.time - see here the configuration and requirements needed to use it on Android (and here has more details about the API) - if you cannot use it, I have left other alternatives below.


If you have two strings in the "HH:mm" format, an alternative is to use one LocalTime, which represents just one time. The "hour:minute" format (each with 2 digits) is in accordance with the standard ISO 8601, and can be done Parsing directly. Ex:

LocalTime horario = LocalTime.parse("14:20");

With that you can do the Parsing of strings. Already to subtract one from the other, what exactly do you want as a result? The total amount of hours and minutes between them? Only the total in minutes (or seconds, or any other unit)?

Anyway, since strings only have hour and minute (assuming seconds are always zero), an alternative would be to calculate the total minutes between them, using a ChronoUnit:

LocalTime inicio = LocalTime.parse("10:00");
LocalTime fim = LocalTime.parse("14:20");
// diferença em minutos
int diffMinutes = (int) ChronoUnit.MINUTES.between(inicio, fim);
int horas = diffMinutes / 60;
int minutos = diffMinutes % 60;
System.out.printf("A diferença entre %s e %s é de %d horas e %d minutos\n",
                  inicio.toString(), fim.toString(), horas, minutos);
// A diferença entre 10:00 e 14:20 é de 4 horas e 20 minutos

The method between returns a long, but how I’m calculating the difference in minutes, and a LocalTime only has the timetable information (i.e., we are assuming that both times refer to the same day), the value will not exceed 1440, so we can do the cast for int hassle-free.

If you want to format the difference as 04:20, can do so:

System.out.printf("%02d:%02d\n", horas, minutos); // 04:20

If you can’t use the java.time, an alternative is to do the calculation manually:

// método auxiliar para "normalizar" o horário
public int totalMinutes(String hora) {
    String[] partes = hora.split(":");

    return Integer.parseInt(partes[0]) * 60 + Integer.parseInt(partes[1]);
}

int diffMinutes = totalMinutes("14:20") - totalMinutes("10:00");
// restante do código igual

Of course, the above method can be improved because it does not check if the string really is in the "HH:mm" format, if the values are correct (for example, "99:99" should give error), etc.


You can also use a SimpleDateFormat, but need to pay attention to some details. This class only works with Date, which in turn represents a timestamp, then it cannot work "only with hours" (if a date is not provided in the string, internally it arrow values default). For example:

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
System.out.println(sdf.parse("10:00")); // Thu Jan 01 10:00:00 BRT 1970

Notice that despite the Parsing be done with time only, the date was set for January 1, 1970. You can see more details about the behavior of Date and SimpleDateFormat in this answer (mainly in the section "Dates and timezones").

Moreover, SimpleDateFormat accepts invalid values such as "99:99", making very strange adjustments:

System.out.println(sdf.parse("99:99")); // Mon Jan 05 04:39:00 BRT 1970

To avoid these problems (among others, how to consider Timezone default of the JVM, and summer time effects can cause problems in calculating the difference), an alternative is to set it to nonlenient (not to consider values like "99:99") and change the Timezone to UTC (which does not suffer summer time effects):

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
sdf.setLenient(false); // setar para não-leniente, assim não aceita valores como 99:99
sdf.setTimeZone(TimeZone.getTimeZone("UTC")); // UTC não sofre efeitos do horário de verão

Date inicio = sdf.parse("10:00");
Date fim = sdf.parse("14:20");

int diffMinutes = (int) ((fim.getTime() - inicio.getTime()) / (1000 * 60));
int horas = diffMinutes / 60;
int minutos = diffMinutes % 60;
System.out.printf("A diferença entre %s e %s é de %d horas e %d minutos\n",
                  sdf.format(inicio), sdf.format(fim), horas, minutos);

I used the method getTime(), that returns the value of timestamp in milliseconds, then subtracting from each other, get the difference in milliseconds, simply adjust the calculations to get the difference in minutes.

Unfortunately, with Date and SimpleDateFormat, there is no other way to calculate the difference between dates.

0

You have to convert your time into a format where you can calculate. One way is this:

String hora_inicio = "14:20";
LocalTime localTime = LocalTime.parse(hora_inicio, DateTimeFormatter.ofPattern("HH:mm"));
int hora = localTime.get(ChronoField.CLOCK_HOUR_OF_DAY);
int minutos = localTime.get(ChronoField.MINUTE_OF_HOUR);

You can use this code to subtract:

// Java 8: java.time.LocalDateTime
LocalDateTime.now().minusHours(1)

Also check:

Apache Dateutils

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.7</version>
</dependency>
  • Thank you so much for your reply. I’m new to java and android studio programming, and I’m not understanding one thing in the code you sent. How can I do the start and end time subtraction by converting each one into hours and minutes? the code LocalDateTime.now().minusHours(1) subtracts the time of the string placed above with the current time?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.