javadatetimedurationtimeofday

Addition of two times in JAVA


I want to make the addition of two times (java.sql.Time) without using any other library (java.date, LocalTime..), I get always the time under 1 hour.

java.sql.Time

Time heureDebut="09:00:00";
Time heureFin="00:15:00";
long heureDebuts = heureDebut.getTime()+heureFin.getTime();
Time tt = new Time(heureDebuts);
//I get 08:15:00 as a result

Solution

  • java.time

    You said you wanted to use no library class but java.sql.Time. Still for you and for everyone else reading this I am suggesting that you don’t use the Time class. One, the class is long outdated, two, the class is horribly designed, three, it’s the wrong class for your purpose, and four, I am not convinced that it can be used for this at all. You may get the impression from the answer by Amine ABBAOUI that it is possible, but that answer is cheating in two ways: It is using methods that have been deprecated for 23 and a half years, which I suggest that no one should want to do either; and it’s doing all of the work outside the Time class.

    java.time is so much nicer to work with. It has been built into Java since Java 8 and has also been backported to Java 6 and 7.

    It’s not perfectly clear to me, but I am assuming that 09:00:00 is a start time and 00:15:00 is a duration, and you want to calculate an end time by adding the duration to the start time.

        LocalTime heureDebut = LocalTime.of(9, 0);
        Duration heureFin = Duration.ofMinutes(15);
        
        LocalTime resultat = heureDebut.plus(heureFin);
        
        System.out.println(resultat);
    

    Output is:

    09:15

    If you were getting Time objects from your database

    If you were getting java.sql.Time objects from an SQL database that stores both start time and duration as time datatype (which is incorrect) and you cannot control the database design: Get LocalTime objects from the database. Convert the duration to a Duration object and then proceed as I did before. For example:

        PreparedStatement stmt = yourDatabaseConnection.prepareStatement(
                "select heure_debut, heure_fin from votre_table where id = 4;");
        ResultSet rs = stmt.executeQuery();
        if (rs.next()) {
            LocalTime heureDebut = rs.getObject("heure_debut", LocalTime.class);
            LocalTime heureFin = rs.getObject("heure_fin", LocalTime.class);
            Duration dur = Duration.ofNanos(heureFin.getLong(ChronoField.NANO_OF_DAY));
            
            LocalTime resultat = heureDebut.plus(dur);
            
            System.out.println(resultat);
        }
    

    Since a LoalTime opposite a Time isn’t connected to any time zone, the conversion above will give you the expected result.

    If you don’t want to use java.time

    If you don’t want to use java.time (not that I’d understand), my best suggestion is that you do everything by hand and don’t use any library class at all. It’s no solution that I recommend, it’s no good solution, but it’s not as bad as trying to make the outdated and poorly designed Time class behave in a way that it was never designed to.

    What went wrong in your code?

    Apart from the fact that you cannot assign a string to a Time object, you have got a time zone offset problem. It seems your time zone was at UTC offset +01:00 on January 1, 1970. A Time is a java.util.Date on January 1, 1970. While not well documented, the time is in the default time zone of the JVM. So your 09:00:00 in your time zone is the same as 08:00:00 UTC. And 00:15:00 is 23:15:00 on the night before (December 31, 1969). The getTime method that you use gets the number of milliseconds since 00:00:00 UTC. So in the first case you get 8 hours worth of milliseconds, and in the second case you get a negative amount equal to minus three quarters of an hour. You added those and got milliseconds enough for 7 hours 15 minutes. You fed those back into a Time object and got 07:15:00 UTC, which prints as 08:15:00 in your time zone.

    Link

    Oracle tutorial: Date Time explaining how to use java.time.