To avoid such surprises, I recommend you do it with the modern date-time API.
import java.time.Duration;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String initialTimeOnSharedPrefs = "01:11:59 AM";
LocalTime startTime = LocalTime.parse(initialTimeOnSharedPrefs,
DateTimeFormatter.ofPattern("h:m:s a", Locale.ENGLISH));
LocalTime now = LocalTime.now();
Duration duration = Duration.between(startTime, now);
// The model is of a directed duration, meaning that the duration may be
// negative. If you want to show the absolute difference, negate it
if (duration.isNegative()) {
duration = duration.negated();
}
// Display duration in its default format i.e. the value of duration#toString
System.out.println(duration);
// #################### Since Java-8 ####################
String formattedDuration = String.format("%d:%d:%d", duration.toHours(), duration.toMinutes() % 60,
duration.toSeconds() % 60);
System.out.println("Duration is " + formattedDuration);
// ######################################################
// #################### Since Java-9 ####################
formattedDuration = String.format("%d:%d:%d", duration.toHoursPart(), duration.toMinutesPart(),
duration.toSecondsPart());
System.out.println("Duration is " + formattedDuration);
// ######################################################
}
}
Output:
PT13H47M39.003708S
Duration is 13:47:39
Duration is 13:47:39
Check Duration#toString
and ISO_8601#Durations to learn more about ISO_8601 format of Duration
.
Correct way of doing it using the legacy API:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
String initialTimeOnSharedPrefs = "01:11:59 AM";
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss a", Locale.ENGLISH);
String strTimeNow = sdf.format(Calendar.getInstance().getTime());
System.out.println(strTimeNow);
Date startTime = sdf.parse(initialTimeOnSharedPrefs);
Date endTime = sdf.parse(strTimeNow);
long duration = Math.abs(endTime.getTime() - startTime.getTime());
long seconds = duration / 1000 % 60;
long minutes = duration / (60 * 1000) % 60;
long hours = duration / (60 * 60 * 1000) % 24;
String formattedDuration = String.format("%d:%d:%d", hours, minutes, seconds);
System.out.println("Duration is " + formattedDuration);
}
}
Output:
02:53:39 PM
Duration is 13:41:40
Some important notes:
- The date-time API of
java.util
and their formatting API, SimpleDateFormat
are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API. For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
- Learn about the modern date-time API from Trail: Date Time.