0

I am using a chronometer to display the time difference.

The initial time is saved onto SharedPreferences: 01:11:59 AM

Then I get the current time:

simpleDateFormat.format(new Date());

which yields the output as: 05:19:03 AM

The time difference of the 2 should be around 4 hours but the chronometer displays this: -691.33.46

Code:

Date date1 = simpleDateFormat.parse(initialTimeOnSharedPrefs);
Date date2 = simpleDateFormat.parse(currentTime);

long millis = date2.getTime() - date1.getTime();

chronometer.setBase(SystemClock.elapsedRealtime() - millis);
chronometer.start();

How can I avoid the negative value & get the correct time set to the chronometer?

Boron
  • 99
  • 10
  • 34

1 Answers1

0

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:

  1. 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.
  2. Learn about the modern date-time API from Trail: Date Time.
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110