How to subtract hours in java?

3

I'm trying to make the difference in hours in my application. The case is as follows: Based on the current current time and current minute , I want to compare another time I have in a string and I need to know how many hours and how many minutes is missing, even if the other string time is from next day.

The time in string has the following format:

String horario = "07:30";

I tried the following code but did not succeed:

     Calendar hoje = Calendar.getInstance();
        String minutosAtual = 
        String.valueOf(hoje.get(Calendar.MINUTE));
        calendar = new GregorianCalendar();
        String strinHora = "14:20";
        String[] hora = strinHora.split(":");
        Integer.parseInt(hora[0]));
        calendar.get(Calendar.MINUTE));
        int minutoInt = calendar.get(Calendar.MINUTE);

        calendar.add(Calendar.HOUR, -Integer.parseInt(hora[0]));
        calendar.add(Calendar.MINUTE, -Integer.parseInt(hora[1]));

        //Define Format of date
        SimpleDateFormat dataFormatada = new 
        SimpleDateFormat("HH:mm");
        String dateStrin = dataFormatada.format(calendar.getTime());
        System.out.println(dateStrin);

Can anyone help me?

    
asked by anonymous 02.09.2017 / 18:16

2 answers

4

If you can / want to use the java.time API, check out my other answer .

But without using java.time , you can do this by creating a Horario class. This Horario class is a wrapper for when you do not have the java.time.LocalTime class available:

import java.util.Calendar;
import java.util.GregorianCalendar;

class Teste {

    private static void mostrar(Horario agora, String objetivo) {
        Horario desejada = Horario.parse(objetivo);
        Horario falta = desejada.diferenca(agora);
        System.out.println(
                "Entre " + agora
                + " e " + desejada
                + ", a diferença é de " + falta
                + ".");
    }

    public static void main(String[] args) {
        Horario agora = Horario.agora();
        mostrar(agora, "07:30");
        mostrar(new Horario( 5, 30), "07:30");
        mostrar(new Horario( 7, 10), "07:30");
        mostrar(new Horario( 0,  0), "07:30");
        mostrar(new Horario( 7,  0), "07:30");
        mostrar(new Horario( 7, 30), "07:30");
        mostrar(new Horario( 7, 31), "07:30");
        mostrar(new Horario(10,  0), "07:30");
        mostrar(new Horario(19, 30), "07:30");
        mostrar(new Horario(23, 59), "07:30");
        mostrar(new Horario( 0,  0), "23:59");
        mostrar(new Horario(23, 59), "00:00");
    }
}

class Horario {
    private final int horas;
    private final int minutos;

    public Horario(int horas, int minutos) {
        if (horas < 0 || horas > 23 || minutos < 0 || minutos > 59) {
            throw new IllegalArgumentException();
        }
        this.horas = horas;
        this.minutos = minutos;
    }

    public int getHoras() {
        return horas;
    }

    public int getMinutos() {
        return minutos;
    }

    public static Horario parse(String input) {
        char[] cs = input.toCharArray();
        if (cs.length != 5) throw new IllegalArgumentException();
        for (int i = 0; i < 5; i++) {
            if (i == 2) continue;
            if (cs[i] < '0' || cs[i] > '9') throw new IllegalArgumentException();
        }
        if (cs[2] != ':') throw new IllegalArgumentException();

        int h = (cs[0] - '0') * 10 + cs[1] - '0';
        int m = (cs[3] - '0') * 10 + cs[4] - '0';
        return new Horario(h, m);
    }

    public static Horario agora() {
        GregorianCalendar gc = new GregorianCalendar();
        return new Horario(gc.get(Calendar.HOUR_OF_DAY), gc.get(Calendar.MINUTE));
    }

    public Horario diferenca(Horario outro) {
        int difHoras = this.horas - outro.horas;
        int difMinutos = this.minutos - outro.minutos;
        while (difMinutos < 0) {
            difMinutos += 60;
            difHoras--;
        }
        while (difHoras < 0) {
            difHoras += 24;
        }
        return new Horario(difHoras, difMinutos);
    }

    @Override
    public String toString() {
        return ((horas < 10) ? "0" : "") + horas + ":" + ((minutos < 10) ? "0" : "") + minutos;
    }
}

The class Horario implements the logic of the time you want. The GregorianCalendar is only used to pick up the clock time and nothing else. After all, working with GregorianCalendar is somewhat torturing (and therefore I try to minimize its use). Besides that, there is no class in the java.util package that represents times with no dates.

Here is the output produced:

Entre 06:27 e 07:30, a diferença é de 01:03.
Entre 05:30 e 07:30, a diferença é de 02:00.
Entre 07:10 e 07:30, a diferença é de 00:20.
Entre 00:00 e 07:30, a diferença é de 07:30.
Entre 07:00 e 07:30, a diferença é de 00:30.
Entre 07:30 e 07:30, a diferença é de 00:00.
Entre 07:31 e 07:30, a diferença é de 23:59.
Entre 10:00 e 07:30, a diferença é de 21:30.
Entre 19:30 e 07:30, a diferença é de 12:00.
Entre 23:59 e 07:30, a diferença é de 07:31.
Entre 00:00 e 23:59, a diferença é de 23:59.
Entre 23:59 e 00:00, a diferença é de 00:01.

See here working on ideone.

    
02.09.2017 / 20:27
3

Use the class java.time.LocalTime . See more about her in this other question and answer from me .

If you want to do without using the java.time package, see the other answer of mine to this question .

Here is a sample code:

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.ResolverStyle;

class TesteDatas {
    private static final DateTimeFormatter FORMATO_HORAS = DateTimeFormatter
            .ofPattern("HH:mm")
            .withResolverStyle(ResolverStyle.STRICT);

    private static LocalTime faltando(LocalTime agora, LocalTime desejada) {
        return desejada.minusHours(agora.getHour()).minusMinutes(agora.getMinute());
    }

    private static void mostrar(LocalTime horario, String objetivo) {
        LocalTime desejada = LocalTime.parse(objetivo, FORMATO_HORAS);
        LocalTime falta = faltando(horario, desejada);
        System.out.println(
                "Entre " + horario.format(FORMATO_HORAS)
                + " e " + desejada.format(FORMATO_HORAS)
                + ", a diferença é de " + falta.format(FORMATO_HORAS)
                + ".");
    }

    public static void main(String[] args) {
        LocalTime agora = LocalTime.now();
        mostrar(agora, "07:30");
        mostrar(LocalTime.of( 5, 30), "07:30");
        mostrar(LocalTime.of( 7, 10), "07:30");
        mostrar(LocalTime.of( 0,  0), "07:30");
        mostrar(LocalTime.of( 7,  0), "07:30");
        mostrar(LocalTime.of( 7, 30), "07:30");
        mostrar(LocalTime.of( 7, 31), "07:30");
        mostrar(LocalTime.of(10,  0), "07:30");
        mostrar(LocalTime.of(19, 30), "07:30");
        mostrar(LocalTime.of(23, 59), "07:30");
        mostrar(LocalTime.of( 0,  0), "23:59");
        mostrar(LocalTime.of(23, 59), "00:00");
    }
}

Here's the output (the first line will vary according to the time you run):

Entre 01:02 e 07:30, a diferença é de 06:28.
Entre 05:30 e 07:30, a diferença é de 02:00.
Entre 07:10 e 07:30, a diferença é de 00:20.
Entre 00:00 e 07:30, a diferença é de 07:30.
Entre 07:00 e 07:30, a diferença é de 00:30.
Entre 07:30 e 07:30, a diferença é de 00:00.
Entre 07:31 e 07:30, a diferença é de 23:59.
Entre 10:00 e 07:30, a diferença é de 21:30.
Entre 19:30 e 07:30, a diferença é de 12:00.
Entre 23:59 e 07:30, a diferença é de 07:31.
Entre 00:00 e 23:59, a diferença é de 23:59.
Entre 23:59 e 00:00, a diferença é de 00:01.

The key to the difference calculation is in the faltando method:

    private static LocalTime faltando(LocalTime agora, LocalTime desejada) {
        return desejada.minusHours(agora.getHour()).minusMinutes(agora.getMinute());
    }

That is, to calculate the difference between the two schedules, subtract the hours and the minutes. Class LocalTime goes around midnight in case of times that would be negative or would exceed 23:59.

See here working on ideone.

Ah, it's important to remember that objects of type java.time.format.DateTimeFormatter need only be created once and can be reused at will. They are thread-safe and immutable and you can put them in static variables. This is something that does not occur with java.util.SimpleDateFormatter .

    
02.09.2017 / 19:11