0

I am trying to calculate the time difference in java by input time format in 12 hours it works well when i input start time 11:58:10 pm and end time 12:02:15 am. But as i enter 12:00:00 am and 12:00:00 pm it give difference 0 minutes. don't know why. Below is my code please let me know where i am wrong.

Scanner input = new Scanner(System.in);
System.out.print("Enter start time (HH:mm:ss aa): ");
String starttime = input.nextLine();

System.out.print("Enter end time (HH:mm:ss aa): ");
String endtime = input.nextLine();

//HH converts hour in 24 hours format (0-23), day calculation
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss aa");

Date d1 = null;
Date d2 = null;

try {
    d1 = format.parse(starttime);
    d2 = format.parse(endtime);

    //in milliseconds
    long diff = d2.getTime() - d1.getTime();

    long diffSeconds = diff / 1000 % 60;
    long diffMinutes = diff / (60 * 1000) % 60;

    System.out.print(diffMinutes + " minutes and "+diffSeconds + " seconds.");
} catch (Exception e) {
    System.out.println("Invalid fromat");
}
8
  • 1
    HH expects the hour in 24 format, not 12. Commented Mar 3, 2020 at 17:40
  • 4
    HH is for 24 hour clock, use hh instead. And it's better not to use the old classes like Date and SimpleDateFormat for this. For one, they are not designed to represent wall clock times. Use LocalTime and DateTimeFormatter Commented Mar 3, 2020 at 17:40
  • i used hh format but still same Commented Mar 3, 2020 at 17:48
  • 1
    Does this have to be Date and SimpleDateFormat? These are regarded as obsolete, new code should use LocalTime, DateTimeFormatter and Duration for this calculation. Commented Mar 3, 2020 at 18:07
  • 1
    Please use java.time. Commented Mar 3, 2020 at 20:20

2 Answers 2

5

The new java.time methods LocalTime, DateTimeFormatter and Duration provide much better methods for handling this. For example:

DateTimeFormatter format = DateTimeFormatter.ofPattern("h:m:s a");

LocalTime time1 = LocalTime.parse("12:00:00 am", format);
LocalTime time2 = LocalTime.parse("2:00:20 pm", format);

Duration dur = Duration.between(time1, time2);

System.out.println(dur.toMinutes() + " minutes " + dur.toSecondsPart() + " seconds");

Note: Duration.toSecondsPart requires Java 9 or later, the rest of this code requires Java 8 or later.

Sign up to request clarification or add additional context in comments.

5 Comments

The class isn't deprecated, and while I don't disagree that this is better, sometimes you have to use Date.
@Makoto Like when you’ve got an evil boss who says so? I can think of very, very few situations.
@OleV.V.: To my understanding, there are some gotchas with Hibernate which exist; there may be no incentive to change from Date to LocalDate or LocalDateTime because that could break contracts in code that is being maintained; etc. It doesn't always have to be someone or something evil in the mix.
Frankly, @Makoto, what are you talking about? The question is about having two strings and calculating the minutes and seconds between them, there’s no persistence involved from what we know. (Besides my Hibernate 5 has been working flawlessly with java.time until now.)
Fair...I think my head was in a different space @OleV.V.. However, I don't see the value in using a different class just because of a typo (as we established, should be lower-case hh as opposed to upper-case). Again, sometimes you just have to use it.
1

The problem is with the following line:

SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss aa");

It should be:

SimpleDateFormat format = new SimpleDateFormat("hh:mm:ss aa");

The symbol, H is used for a time in 24-hour format while h is used for that in 12-hour format.

Your calculation of diffMinutes is also wrong.

Do it as follows:

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

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Enter start time (hh:mm:ss aa): ");
        String starttime = input.nextLine();

        System.out.print("Enter end time (hh:mm:ss aa): ");
        String endtime = input.nextLine();

        SimpleDateFormat format = new SimpleDateFormat("hh:mm:ss aa");

        Date d1 = null;
        Date d2 = null;

        try {
            d1 = format.parse(starttime);
            d2 = format.parse(endtime);

            // in milliseconds
            long diff = Math.abs(d2.getTime() - d1.getTime());

            long diffSeconds = (diff / 1000) % 60;
            long diffMinutes = (diff / (60 * 1000));

            System.out.print(diffMinutes + " minutes and " + diffSeconds + " seconds.");
        } catch (Exception e) {
            System.out.println("Invalid fromat");
        }
    }
}

A sample run:

Enter start time (hh:mm:ss aa): 10:20:30 am
Enter end time (hh:mm:ss aa): 10:20:13 pm
719 minutes and 43 seconds.

Notes:

  1. As @greg-449 has mentioned, you should strive to use modern date-time API.
  2. The difference between two quantities is an absolute value which is always positive i.e. the difference between 2 and 5 = difference between 5 and 2 = 3. Math.abs gives you the absolute value of a number which suites best for finding the difference between two quantities.
  3. You need to understand that without telling about the date, the difference between two times is always considered for the same date i.e. the difference between 12:02:15 am and 11:58:10 pm = difference between 11:58:10 pm and 12:02:15 am = 1435 minutes and 55 seconds. The difference between 11:58:10 pm on one date and 12:02:15 am on the next date is 4 minutes 5 seconds. However, your input is only for times and does not have date element and therefore the difference has been considered for the same date. Given below is the program to consider a date with time.

Program considering a date with time:

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

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Enter start time (dd.MM.yyyy at hh:mm:ss aa): ");
        String starttime = input.nextLine();

        System.out.print("Enter end time (dd.MM.yyyy at hh:mm:ss aa): ");
        String endtime = input.nextLine();

        SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy 'at' hh:mm:ss aa");

        Date d1 = null;
        Date d2 = null;

        try {
            d1 = format.parse(starttime);
            d2 = format.parse(endtime);

            // in milliseconds
            long diff = Math.abs(d2.getTime() - d1.getTime());

            long diffSeconds = (diff / 1000) % 60;
            long diffMinutes = (diff / (60 * 1000));

            System.out.print(diffMinutes + " minutes and " + diffSeconds + " seconds.");
        } catch (Exception e) {
            System.out.println("Invalid fromat");
        }
    }
}

A sample run:

Enter start time (dd.MM.yyyy at hh:mm:ss aa): 03.03.2020 at 11:58:10 pm
Enter end time (dd.MM.yyyy at hh:mm:ss aa): 04.03.2020 at 12:02:15 am
4 minutes and 5 seconds.

2 Comments

its not giving accurate with time 11:58:10 pm and 12:02:15 am
I've updated the answer with some notes. I hope, it helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.